Bug 1599046 - P2. Remove calling NotifyOnContentBlocking in the child process r=timhuang,Ehsan

This patch does the followings:
1. Remove NotifyOnContentBlocking in WindowOuter and all the call sites.
   This is because all the content blocking event handling is moved to the parent.

2. Replace UrlClassifierCommon::NotifyChannelBlocked with AntiTrackingCommon:::NotifyContentBlockingEventInParent.
   This is because we don't need to pass the request to the child anymore, which was implemented in NotifyChannelBlocked previously.

3. Add NotifyContentBlockingEvent* utility functions to AntiTrackingCommon.cpp.

4. Update AntiTrackingCommon::NotifyBlockingDecision, when it is called in the parent,
   do not send requests to the child, notify the parent directly

Depends on D56874

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Dimi Lee 2020-01-27 10:39:43 +00:00
Родитель f9ac16c330
Коммит 6b66f4ad81
8 изменённых файлов: 167 добавлений и 186 удалений

Просмотреть файл

@ -5325,14 +5325,6 @@ void nsGlobalWindowOuter::FirePopupBlockedEvent(
aDoc->DispatchEvent(*event);
}
void nsGlobalWindowOuter::NotifyContentBlockingEvent(
unsigned aEvent, nsIChannel* aChannel, bool aBlocked, nsIURI* aURIHint,
nsIChannel* aTrackingChannel,
const mozilla::Maybe<AntiTrackingCommon::StorageAccessGrantedReason>&
aReason) {
// TODO: This function will be removed in the next patch
}
// static
bool nsGlobalWindowOuter::CanSetProperty(const char* aPrefName) {
// Chrome can set any property.

Просмотреть файл

@ -470,13 +470,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
Document* aDoc, nsIURI* aPopupURI, const nsAString& aPopupWindowName,
const nsAString& aPopupWindowFeatures) override;
virtual void NotifyContentBlockingEvent(
unsigned aEvent, nsIChannel* aChannel, bool aBlocked, nsIURI* aURIHint,
nsIChannel* aTrackingChannel,
const mozilla::Maybe<
mozilla::AntiTrackingCommon::StorageAccessGrantedReason>& aReason)
override;
void AddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const;
void AllowScriptsToClose() { mAllowScriptsToClose = true; }

Просмотреть файл

@ -987,13 +987,6 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
const nsAString& aPopupWindowName,
const nsAString& aPopupWindowFeatures) = 0;
virtual void NotifyContentBlockingEvent(
unsigned aEvent, nsIChannel* aChannel, bool aBlocked, nsIURI* aURIHint,
nsIChannel* aTrackingChannel,
const mozilla::Maybe<
mozilla::AntiTrackingCommon::StorageAccessGrantedReason>& aReason =
mozilla::Nothing()) = 0;
// WebIDL-ish APIs
void MarkUncollectableForCCGeneration(uint32_t aGeneration) {
mMarkedCCGeneration = aGeneration;

Просмотреть файл

@ -33,18 +33,21 @@ interface nsIParentChannel : nsIStreamListener
* Called to notify the HttpChannelChild that channel classifier protection
* was disabled for this load.
*/
// TODO: Remove this in the next patch
[noscript] void notifyChannelClassifierProtectionDisabled(in uint32_t aAcceptedReason);
/**
* Called to notify the HttpChannelChild that cookie has been allowed for
* this load.
*/
// TODO: Remove this in the next patch
[noscript] void notifyCookieAllowed();
/**
* Called to notify the HttpChannelChild that cookie has been blocked for
* this load.
*/
// TODO: Remove this in the next patch
[noscript] void notifyCookieBlocked(in uint32_t aRejectedReason);
/**

Просмотреть файл

@ -54,79 +54,7 @@ bool UrlClassifierCommon::AddonMayLoad(nsIChannel* aChannel, nsIURI* aURI) {
/* static */
void UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
nsIChannel* aChannel, uint32_t aEvent) {
// Can be called in EITHER the parent or child process.
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(aChannel, parentChannel);
if (parentChannel) {
// This channel is a parent-process proxy for a child process request.
// Tell the child process channel to do this as well.
parentChannel->NotifyChannelClassifierProtectionDisabled(aEvent);
}
nsCOMPtr<nsIURI> uriBeingLoaded =
AntiTrackingCommon::MaybeGetDocumentURIBeingLoaded(aChannel);
NotifyChannelBlocked(aChannel, uriBeingLoaded, aEvent);
}
/* static */
void UrlClassifierCommon::NotifyChannelBlocked(nsIChannel* aChannel,
nsIURI* aURIBeingLoaded,
unsigned aBlockedReason) {
MOZ_ASSERT(aChannel);
nsCOMPtr<nsIURI> uri;
aChannel->GetURI(getter_AddRefs(uri));
// We would notify the OnContentBlockingEvent via the top-level
// WindowGlobalParent if it is in the parent process.
if (XRE_IsParentProcess()) {
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
RefPtr<dom::BrowsingContext> bc;
loadInfo->GetBrowsingContext(getter_AddRefs(bc));
if (!bc || bc->IsDiscarded()) {
return;
}
// Get the top-level browsing context.
bc = bc->Top();
RefPtr<dom::WindowGlobalParent> wgp =
bc->Canonical()->GetCurrentWindowGlobal();
NS_ENSURE_TRUE_VOID(wgp);
nsTArray<nsCString> trackingFullHashes;
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
do_QueryInterface(aChannel);
if (classifiedChannel) {
Unused << classifiedChannel->GetMatchedTrackingFullHashes(
trackingFullHashes);
}
wgp->NotifyContentBlockingEvent(aBlockedReason, aChannel, true, uri,
trackingFullHashes);
return;
}
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
if (NS_WARN_IF(!thirdPartyUtil)) {
return;
}
nsCOMPtr<mozIDOMWindowProxy> win;
nsresult rv = thirdPartyUtil->GetTopWindowForChannel(
aChannel, aURIBeingLoaded, getter_AddRefs(win));
NS_ENSURE_SUCCESS_VOID(rv);
auto* pwin = nsPIDOMWindowOuter::From(win);
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
if (!docShell) {
return;
}
RefPtr<dom::Document> doc = docShell->GetDocument();
NS_ENSURE_TRUE_VOID(doc);
pwin->NotifyContentBlockingEvent(aBlockedReason, aChannel, true, uri,
aChannel);
// TODO: Remove this in the next patch
}
/* static */
@ -271,26 +199,25 @@ nsresult UrlClassifierCommon::SetBlockedContent(nsIChannel* channel,
classifiedChannel->SetMatchedInfo(aList, aProvider, aFullHash);
}
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(channel, parentChannel);
nsCOMPtr<nsIURI> uriBeingLoaded =
AntiTrackingCommon::MaybeGetDocumentURIBeingLoaded(channel);
if (XRE_IsParentProcess()) {
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(channel, parentChannel);
if (parentChannel) {
// This channel is a parent-process proxy for a child process request.
// Tell the child process channel to do this as well.
// TODO: We can remove the code sending the IPC to content to update
// matched info once we move the ContentBlockingLog into the parent.
// This would be done in Bug 1601063.
parentChannel->SetClassifierMatchedInfo(aList, aProvider, aFullHash);
}
unsigned state =
UrlClassifierFeatureFactory::GetClassifierBlockingEventCode(aErrorCode);
if (!state) {
state = nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
}
unsigned state =
UrlClassifierFeatureFactory::GetClassifierBlockingEventCode(aErrorCode);
if (!state) {
state = nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
}
AntiTrackingCommon::NotifyContentBlockingEvent(channel, state);
if (parentChannel) {
// This channel is a parent-process proxy for a child process request.
// Tell the child process channel to do this as well.
// TODO: We can remove the code sending the IPC to content to update
// matched info once we move the ContentBlockingLog into the parent.
// This would be done in Bug 1601063.
parentChannel->SetClassifierMatchedInfo(aList, aProvider, aFullHash);
UrlClassifierCommon::NotifyChannelBlocked(channel, uriBeingLoaded, state);
return NS_OK;
}
@ -299,6 +226,8 @@ nsresult UrlClassifierCommon::SetBlockedContent(nsIChannel* channel,
return NS_OK;
}
nsCOMPtr<nsIURI> uriBeingLoaded =
AntiTrackingCommon::MaybeGetDocumentURIBeingLoaded(channel);
nsCOMPtr<mozIDOMWindowProxy> win;
rv = thirdPartyUtil->GetTopWindowForChannel(channel, uriBeingLoaded,
getter_AddRefs(win));
@ -311,8 +240,6 @@ nsresult UrlClassifierCommon::SetBlockedContent(nsIChannel* channel,
RefPtr<dom::Document> doc = docShell->GetDocument();
NS_ENSURE_TRUE(doc, NS_OK);
UrlClassifierCommon::NotifyChannelBlocked(channel, uriBeingLoaded, state);
// Log a warning to the web console.
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
@ -488,6 +415,7 @@ void LowerPriorityHelper(nsIChannel* aChannel) {
void UrlClassifierCommon::AnnotateChannel(nsIChannel* aChannel,
uint32_t aClassificationFlags,
uint32_t aLoadingState) {
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(aChannel);
nsCOMPtr<nsIURI> chanURI;
@ -515,8 +443,7 @@ void UrlClassifierCommon::AnnotateChannel(nsIChannel* aChannel,
IsCryptominingClassificationFlag(aClassificationFlags);
if (validClassificationFlags && isThirdPartyWithTopLevelWinURI) {
UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
aChannel, aLoadingState);
AntiTrackingCommon::NotifyContentBlockingEvent(aChannel, aLoadingState);
}
if (isThirdPartyWithTopLevelWinURI &&

Просмотреть файл

@ -81,11 +81,6 @@ class UrlClassifierCommon final {
const std::vector<ClassificationData>& aData, uint32_t aDefaultFlag);
private:
// aBlockedReason must be one of the nsIWebProgressListener state.
static void NotifyChannelBlocked(nsIChannel* aChannel,
nsIURI* aURIBeingLoaded,
unsigned aBlockedReason);
static uint32_t TableToClassificationFlag(
const nsACString& aTable, const std::vector<ClassificationData>& aData);
};

Просмотреть файл

@ -7,7 +7,9 @@
#include "AntiTrackingCommon.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/ipc/MessageChannel.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/HashFunctions.h"
@ -845,21 +847,11 @@ bool CheckAntiTrackingPermission(nsIPrincipal* aPrincipal,
return true;
}
void NotifyBlockingDecisionInternal(
nsIChannel* aReportingChannel, nsIChannel* aTrackingChannel,
AntiTrackingCommon::BlockingDecision aDecision, uint32_t aRejectedReason,
nsIURI* aURI, nsPIDOMWindowOuter* aWindow) {
MOZ_DIAGNOSTIC_ASSERT_IF(
nsGlobalWindowOuter::Cast(aWindow)->IsChromeWindow(),
aDecision == AntiTrackingCommon::BlockingDecision::eAllow);
if (aDecision == AntiTrackingCommon::BlockingDecision::eBlock) {
AntiTrackingCommon::NotifyContentBlockingEvent(aWindow, aReportingChannel,
aTrackingChannel, true,
aRejectedReason, aURI);
ReportBlockingToConsole(aWindow, aURI, aRejectedReason);
}
// This API finishes the remaining work left in NotifyBlockingDecisionInternal.
void NotifyAllowDecisionInternal(nsIChannel* aReportingChannel,
nsIChannel* aTrackingChannel, nsIURI* aURI,
nsPIDOMWindowOuter* aWindow) {
// This can be called in either the parent process or the child processes.
// Now send the generic "cookies loaded" notifications, from the most generic
// to the most specific.
@ -890,6 +882,111 @@ void NotifyBlockingDecisionInternal(
}
}
void NotifyBlockingDecisionInternal(
nsIChannel* aReportingChannel, nsIChannel* aTrackingChannel,
AntiTrackingCommon::BlockingDecision aDecision, uint32_t aRejectedReason,
nsIURI* aURI, nsPIDOMWindowOuter* aWindow) {
MOZ_ASSERT(aWindow);
// When this is called with system priviledged, the decision should always be
// ALLOW, and we can also stop processing this event.
if (nsGlobalWindowOuter::Cast(aWindow)->GetPrincipal() ==
nsContentUtils::GetSystemPrincipal()) {
MOZ_DIAGNOSTIC_ASSERT(aDecision ==
AntiTrackingCommon::BlockingDecision::eAllow);
return;
}
if (aDecision == AntiTrackingCommon::BlockingDecision::eBlock) {
AntiTrackingCommon::NotifyContentBlockingEvent(aWindow, aReportingChannel,
aTrackingChannel, true,
aRejectedReason, aURI);
ReportBlockingToConsole(aWindow, aURI, aRejectedReason);
}
NotifyAllowDecisionInternal(aReportingChannel, aTrackingChannel, aURI,
aWindow);
}
void NotifyBlockingDecisionInternal(
nsIChannel* aReportingChannel, nsIChannel* aTrackingChannel,
AntiTrackingCommon::BlockingDecision aDecision, uint32_t aRejectedReason,
nsIURI* aURI) {
// Can be called only in the parent process when there is no window.
MOZ_ASSERT(XRE_IsParentProcess());
if (aDecision == AntiTrackingCommon::BlockingDecision::eBlock) {
AntiTrackingCommon::NotifyContentBlockingEvent(nullptr, aReportingChannel,
aTrackingChannel, true,
aRejectedReason, aURI);
}
NotifyAllowDecisionInternal(aReportingChannel, aTrackingChannel, aURI,
nullptr);
}
// Send a message to notify OnContentBlockingEvent in the parent, which will
// update the ContentBlockingLog in the parent.
void NotifyContentBlockingEventInChild(
nsPIDOMWindowOuter* aWindow, nsIChannel* aReportingChannel,
nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
nsIURI* aURI,
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason) {
MOZ_ASSERT(XRE_IsContentProcess());
MOZ_ASSERT(aWindow);
RefPtr<dom::BrowserChild> browserChild = dom::BrowserChild::GetFrom(aWindow);
NS_ENSURE_TRUE_VOID(browserChild);
nsTArray<nsCString> trackingFullHashes;
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
do_QueryInterface(aTrackingChannel);
if (classifiedChannel) {
Unused << classifiedChannel->GetMatchedTrackingFullHashes(
trackingFullHashes);
}
browserChild->NotifyContentBlockingEvent(aRejectedReason, aReportingChannel,
aBlocked, aURI, trackingFullHashes,
aReason);
}
// Update the ContentBlockingLog of the top-level WindowGlobalParent of
// the reporting channel.
void NotifyContentBlockingEventInParent(
nsIChannel* aReportingChannel, nsIChannel* aTrackingChannel, bool aBlocked,
uint32_t aRejectedReason, nsIURI* aURI,
const Maybe<AntiTrackingCommon::StorageAccessGrantedReason>& aReason) {
MOZ_ASSERT(XRE_IsParentProcess());
nsCOMPtr<nsILoadInfo> loadInfo = aReportingChannel->LoadInfo();
RefPtr<dom::BrowsingContext> bc;
loadInfo->GetBrowsingContext(getter_AddRefs(bc));
if (!bc || bc->IsDiscarded()) {
return;
}
bc = bc->Top();
RefPtr<dom::WindowGlobalParent> wgp =
bc->Canonical()->GetCurrentWindowGlobal();
NS_ENSURE_TRUE_VOID(wgp);
nsTArray<nsCString> trackingFullHashes;
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
do_QueryInterface(aTrackingChannel);
if (classifiedChannel) {
Unused << classifiedChannel->GetMatchedTrackingFullHashes(
trackingFullHashes);
}
wgp->NotifyContentBlockingEvent(aRejectedReason, aReportingChannel, aBlocked,
aURI, trackingFullHashes, aReason);
}
} // namespace
/* static */ RefPtr<AntiTrackingCommon::StorageAccessGrantPromise>
@ -2035,26 +2132,14 @@ void AntiTrackingCommon::NotifyBlockingDecision(nsIChannel* aChannel,
return;
}
// Can be called in EITHER the parent or child process.
if (XRE_IsParentProcess()) {
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(aChannel, parentChannel);
if (parentChannel) {
// This channel is a parent-process proxy for a child process request.
// Tell the child process channel to do this instead.
if (aDecision == BlockingDecision::eBlock) {
parentChannel->NotifyCookieBlocked(aRejectedReason);
} else {
parentChannel->NotifyCookieAllowed();
}
nsCOMPtr<nsIURI> uri;
aChannel->GetURI(getter_AddRefs(uri));
// TODO: For ETP fission, we don't need to notify the
// OnContentBlockingEvent in the current stage. Because we still
// send a IPC to the content process in order to update the log in
// the content. And the content would send back to parent to notify
// the event. So, we don't need to notify here. But, we will have to
// notify here once the log move to parent entirely (Bug 1599046).
}
// Can be called in EITHER the parent or child process.
// Window is only needed while in child processes.
if (XRE_IsParentProcess()) {
NotifyBlockingDecisionInternal(aChannel, aChannel, aDecision,
aRejectedReason, uri);
return;
}
@ -2076,9 +2161,6 @@ void AntiTrackingCommon::NotifyBlockingDecision(nsIChannel* aChannel,
return;
}
nsCOMPtr<nsIURI> uri;
aChannel->GetURI(getter_AddRefs(uri));
NotifyBlockingDecisionInternal(aChannel, aChannel, aDecision, aRejectedReason,
uri, pwin);
}
@ -2257,39 +2339,32 @@ already_AddRefed<nsIURI> AntiTrackingCommon::MaybeGetDocumentURIBeingLoaded(
return uriBeingLoaded.forget();
}
/* static */
void AntiTrackingCommon::NotifyContentBlockingEvent(nsIChannel* aChannel,
uint32_t aRejectedReason) {
MOZ_ASSERT(XRE_IsParentProcess() && aChannel);
nsCOMPtr<nsIURI> uri;
aChannel->GetURI(getter_AddRefs(uri));
return AntiTrackingCommon::NotifyContentBlockingEvent(
nullptr, aChannel, aChannel, true, aRejectedReason, uri);
}
/* static */
void AntiTrackingCommon::NotifyContentBlockingEvent(
nsPIDOMWindowOuter* aWindow, nsIChannel* aReportingChannel,
nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,
nsIURI* aURI, const Maybe<StorageAccessGrantedReason>& aReason) {
MOZ_ASSERT(aWindow);
// Log the content blocking event. This should be removed in Bug 1599046.
aWindow->NotifyContentBlockingEvent(aRejectedReason, aReportingChannel,
aBlocked, aURI, aTrackingChannel,
aReason);
RefPtr<dom::BrowserChild> browserChild = dom::BrowserChild::GetFrom(aWindow);
NS_ENSURE_TRUE_VOID(browserChild);
nsTArray<nsCString> trackingFullHashes;
nsCOMPtr<nsIClassifiedChannel> classifiedChannel =
do_QueryInterface(aTrackingChannel);
if (classifiedChannel) {
Unused << classifiedChannel->GetMatchedTrackingFullHashes(
trackingFullHashes);
if (XRE_IsParentProcess()) {
NotifyContentBlockingEventInParent(aReportingChannel, aTrackingChannel,
aBlocked, aRejectedReason, aURI,
aReason);
} else {
NotifyContentBlockingEventInChild(aWindow, aReportingChannel,
aTrackingChannel, aBlocked,
aRejectedReason, aURI, aReason);
}
// Send a message to notify OnContentBlockingEvent in the parent, which will
// update the ContentBlockingLog in the parent.
// We also notify the event in the content above since we haven't move the log
// into the parent process entirely. So, we need to notify and update the
// ContentBlockingLog in the content processes. We can remove this once we
// finish the Bug 1599046.
browserChild->NotifyContentBlockingEvent(aRejectedReason, aReportingChannel,
aBlocked, aURI, trackingFullHashes,
aReason);
}
/* static */

Просмотреть файл

@ -181,6 +181,9 @@ class AntiTrackingCommon final {
static already_AddRefed<nsIURI> MaybeGetDocumentURIBeingLoaded(
nsIChannel* aChannel);
static void NotifyContentBlockingEvent(nsIChannel* aChannel,
uint32_t aRejectedReason);
static void NotifyContentBlockingEvent(
nsPIDOMWindowOuter* aWindow, nsIChannel* aReportingChannel,
nsIChannel* aTrackingChannel, bool aBlocked, uint32_t aRejectedReason,