Store Ad Click Attribution requests in the network process
[WebKit-https.git] / Source / WebCore / loader / ResourceLoadObserver.cpp
index 95d6595..a363155 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,7 +40,7 @@
 #include "ScriptExecutionContext.h"
 #include "SecurityOrigin.h"
 #include "Settings.h"
-#include "URL.h"
+#include <wtf/URL.h>
 
 namespace WebCore {
 
@@ -69,6 +69,30 @@ void ResourceLoadObserver::setRequestStorageAccessUnderOpenerCallback(WTF::Funct
     m_requestStorageAccessUnderOpenerCallback = WTFMove(callback);
 }
 
+void ResourceLoadObserver::setLogUserInteractionNotificationCallback(Function<void(PAL::SessionID, const String&)>&& callback)
+{
+    ASSERT(!m_logUserInteractionNotificationCallback);
+    m_logUserInteractionNotificationCallback = WTFMove(callback);
+}
+
+void ResourceLoadObserver::setLogWebSocketLoadingNotificationCallback(Function<void(PAL::SessionID, const String&, const String&, WallTime)>&& callback)
+{
+    ASSERT(!m_logWebSocketLoadingNotificationCallback);
+    m_logWebSocketLoadingNotificationCallback = WTFMove(callback);
+}
+
+void ResourceLoadObserver::setLogSubresourceLoadingNotificationCallback(Function<void(PAL::SessionID, const String&, const String&, WallTime)>&& callback)
+{
+    ASSERT(!m_logSubresourceLoadingNotificationCallback);
+    m_logSubresourceLoadingNotificationCallback = WTFMove(callback);
+}
+
+void ResourceLoadObserver::setLogSubresourceRedirectNotificationCallback(Function<void(PAL::SessionID, const String&, const String&)>&& callback)
+{
+    ASSERT(!m_logSubresourceRedirectNotificationCallback);
+    m_logSubresourceRedirectNotificationCallback = WTFMove(callback);
+}
+    
 ResourceLoadObserver::ResourceLoadObserver()
     : m_notificationTimer(*this, &ResourceLoadObserver::notifyObserver)
 {
@@ -116,9 +140,12 @@ void ResourceLoadObserver::logSubresourceLoading(const Frame* frame, const Resou
     bool shouldCallNotificationCallback = false;
     {
         auto& targetStatistics = ensureResourceStatisticsForPrimaryDomain(targetPrimaryDomain);
-        targetStatistics.lastSeen = ResourceLoadStatistics::reduceTimeResolution(WallTime::now());
+        auto lastSeen = ResourceLoadStatistics::reduceTimeResolution(WallTime::now());
+        targetStatistics.lastSeen = lastSeen;
         if (targetStatistics.subresourceUnderTopFrameOrigins.add(mainFramePrimaryDomain).isNewEntry)
             shouldCallNotificationCallback = true;
+
+        m_logSubresourceLoadingNotificationCallback(page->sessionID(), targetPrimaryDomain, mainFramePrimaryDomain, lastSeen);
     }
 
     if (isRedirect) {
@@ -129,15 +156,17 @@ void ResourceLoadObserver::logSubresourceLoading(const Frame* frame, const Resou
 
         if (isNewRedirectToEntry || isNewRedirectFromEntry)
             shouldCallNotificationCallback = true;
+
+        m_logSubresourceRedirectNotificationCallback(page->sessionID(), sourcePrimaryDomain, targetPrimaryDomain);
     }
 
     if (shouldCallNotificationCallback)
         scheduleNotificationIfNeeded();
 }
 
-void ResourceLoadObserver::logWebSocketLoading(const URL& targetURL, const URL& mainFrameURL, bool usesEphemeralSession)
+void ResourceLoadObserver::logWebSocketLoading(const URL& targetURL, const URL& mainFrameURL, PAL::SessionID sessionID)
 {
-    if (!shouldLog(usesEphemeralSession))
+    if (!shouldLog(sessionID.isEphemeral()))
         return;
 
     auto targetHost = targetURL.host();
@@ -152,10 +181,14 @@ void ResourceLoadObserver::logWebSocketLoading(const URL& targetURL, const URL&
     if (targetPrimaryDomain == mainFramePrimaryDomain)
         return;
 
+    auto lastSeen = ResourceLoadStatistics::reduceTimeResolution(WallTime::now());
+
     auto& targetStatistics = ensureResourceStatisticsForPrimaryDomain(targetPrimaryDomain);
-    targetStatistics.lastSeen = ResourceLoadStatistics::reduceTimeResolution(WallTime::now());
+    targetStatistics.lastSeen = lastSeen;
     if (targetStatistics.subresourceUnderTopFrameOrigins.add(mainFramePrimaryDomain).isNewEntry)
         scheduleNotificationIfNeeded();
+
+    m_logWebSocketLoadingNotificationCallback(sessionID, targetPrimaryDomain, mainFramePrimaryDomain, lastSeen);
 }
 
 void ResourceLoadObserver::logUserInteractionWithReducedTimeResolution(const Document& document)
@@ -181,15 +214,18 @@ void ResourceLoadObserver::logUserInteractionWithReducedTimeResolution(const Doc
     statistics.mostRecentUserInteractionTime = newTime;
 
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
-    if (auto* opener = document.frame()->loader().opener()) {
-        if (auto* openerDocument = opener->document()) {
-            if (auto* openerFrame = openerDocument->frame()) {
-                if (auto openerPageID = openerFrame->loader().client().pageID()) {
-                    requestStorageAccessUnderOpener(domain, openerPageID.value(), *openerDocument);
+    if (auto* frame = document.frame()) {
+        if (auto* opener = frame->loader().opener()) {
+            if (auto* openerDocument = opener->document()) {
+                if (auto* openerFrame = openerDocument->frame()) {
+                    if (auto openerPageID = openerFrame->loader().client().pageID())
+                        requestStorageAccessUnderOpener(domain, openerPageID.value(), *openerDocument);
                 }
             }
         }
     }
+
+    m_logUserInteractionNotificationCallback(document.sessionID(), domain);
 #endif
 
     m_notificationTimer.stop();
@@ -224,7 +260,7 @@ void ResourceLoadObserver::requestStorageAccessUnderOpener(const String& domainI
     auto openerPrimaryDomain = primaryDomain(openerUrl);
     if (domainInNeedOfStorageAccess != openerPrimaryDomain
         && !openerDocument.hasRequestedPageSpecificStorageAccessWithUserInteraction(domainInNeedOfStorageAccess)
-        && !equalIgnoringASCIICase(openerUrl.string(), blankURL())) {
+        && !equalIgnoringASCIICase(openerUrl.string(), WTF::blankURL())) {
         m_requestStorageAccessUnderOpenerCallback(domainInNeedOfStorageAccess, openerPageID, openerPrimaryDomain);
         // Remember user interaction-based requests since they don't need to be repeated.
         openerDocument.setHasRequestedPageSpecificStorageAccessWithUserInteraction(domainInNeedOfStorageAccess);
@@ -234,6 +270,7 @@ void ResourceLoadObserver::requestStorageAccessUnderOpener(const String& domainI
 
 void ResourceLoadObserver::logFontLoad(const Document& document, const String& familyName, bool loadStatus)
 {
+#if ENABLE(WEB_API_STATISTICS)
     if (!shouldLog(document.sessionID().isEphemeral()))
         return;
     auto registrableDomain = primaryDomain(document.url());
@@ -251,10 +288,16 @@ void ResourceLoadObserver::logFontLoad(const Document& document, const String& f
         shouldCallNotificationCallback = true;
     if (shouldCallNotificationCallback)
         scheduleNotificationIfNeeded();
+#else
+    UNUSED_PARAM(document);
+    UNUSED_PARAM(familyName);
+    UNUSED_PARAM(loadStatus);
+#endif
 }
     
 void ResourceLoadObserver::logCanvasRead(const Document& document)
 {
+#if ENABLE(WEB_API_STATISTICS)
     if (!shouldLog(document.sessionID().isEphemeral()))
         return;
     auto registrableDomain = primaryDomain(document.url());
@@ -263,10 +306,14 @@ void ResourceLoadObserver::logCanvasRead(const Document& document)
     statistics.canvasActivityRecord.wasDataRead = true;
     if (statistics.topFrameRegistrableDomainsWhichAccessedWebAPIs.add(mainFrameRegistrableDomain).isNewEntry)
         scheduleNotificationIfNeeded();
+#else
+    UNUSED_PARAM(document);
+#endif
 }
 
 void ResourceLoadObserver::logCanvasWriteOrMeasure(const Document& document, const String& textWritten)
 {
+#if ENABLE(WEB_API_STATISTICS)
     if (!shouldLog(document.sessionID().isEphemeral()))
         return;
     auto registrableDomain = primaryDomain(document.url());
@@ -279,10 +326,15 @@ void ResourceLoadObserver::logCanvasWriteOrMeasure(const Document& document, con
         shouldCallNotificationCallback = true;
     if (shouldCallNotificationCallback)
         scheduleNotificationIfNeeded();
+#else
+    UNUSED_PARAM(document);
+    UNUSED_PARAM(textWritten);
+#endif
 }
     
 void ResourceLoadObserver::logNavigatorAPIAccessed(const Document& document, const ResourceLoadStatistics::NavigatorAPI functionName)
 {
+#if ENABLE(WEB_API_STATISTICS)
     if (!shouldLog(document.sessionID().isEphemeral()))
         return;
     auto registrableDomain = primaryDomain(document.url());
@@ -297,10 +349,15 @@ void ResourceLoadObserver::logNavigatorAPIAccessed(const Document& document, con
         shouldCallNotificationCallback = true;
     if (shouldCallNotificationCallback)
         scheduleNotificationIfNeeded();
+#else
+    UNUSED_PARAM(document);
+    UNUSED_PARAM(functionName);
+#endif
 }
     
 void ResourceLoadObserver::logScreenAPIAccessed(const Document& document, const ResourceLoadStatistics::ScreenAPI functionName)
 {
+#if ENABLE(WEB_API_STATISTICS)
     if (!shouldLog(document.sessionID().isEphemeral()))
         return;
     auto registrableDomain = primaryDomain(document.url());
@@ -315,6 +372,10 @@ void ResourceLoadObserver::logScreenAPIAccessed(const Document& document, const
         shouldCallNotificationCallback = true;
     if (shouldCallNotificationCallback)
         scheduleNotificationIfNeeded();
+#else
+    UNUSED_PARAM(document);
+    UNUSED_PARAM(functionName);
+#endif
 }
     
 ResourceLoadStatistics& ResourceLoadObserver::ensureResourceStatisticsForPrimaryDomain(const String& primaryDomain)