Create a WebResourceLoadStatisticsStore attached to the NetworkSession
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Jan 2019 03:28:48 +0000 (03:28 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Jan 2019 03:28:48 +0000 (03:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=193261
<rdar://problem/47158616>

Reviewed by Alex Christensen.

This patch modifies NetworkSession so that it owns a WebResourceLoadStatisticsStore
object. This object is only created if the ResourceLoadStatistics feature is turned on.

The patch also modifies WebResourceLoadStatisticsStore so that it can be constructed
with an owning NetworkSession as an alternative to the current practice of using a
WebsiteDataStore object.

Two initial messages from the WebContent process are added (logFrameNavigation and
logUserNavigation) that notify the network process of these actions. Currently they
are called in addition the calls to the WebsiteDataStore object. These redundant calls
will be removed in a future patch.

This patch forces the ResourceLoadStatistics code in the NetworkSession to be off by
default, so there should be no change in behavior with this patch.

* NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp:
(WebKit::ResourceLoadStatisticsMemoryStore::updateClientSideCookiesAgeCap):
* NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
(WebKit::WebResourceLoadStatisticsStore::hasStorageAccessForFrame):
(WebKit::WebResourceLoadStatisticsStore::callHasStorageAccessForFrameHandler):
(WebKit::WebResourceLoadStatisticsStore::grantStorageAccess):
(WebKit::WebResourceLoadStatisticsStore::callGrantStorageAccessHandler):
(WebKit::WebResourceLoadStatisticsStore::removeAllStorageAccess):
(WebKit::WebResourceLoadStatisticsStore::logFrameNavigation):
(WebKit::WebResourceLoadStatisticsStore::logUserInteraction):
(WebKit::WebResourceLoadStatisticsStore::setCacheMaxAgeCapForPrevalentResources):
(WebKit::WebResourceLoadStatisticsStore::setCacheMaxAgeCap):
(WebKit::WebResourceLoadStatisticsStore::updatePrevalentDomainsToBlockCookiesFor):
(WebKit::WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler):
(WebKit::WebResourceLoadStatisticsStore::removePrevalentDomains):
(WebKit::WebResourceLoadStatisticsStore::callRemoveDomainsHandler):
* NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::initializeNetworkProcess):
(WebKit::NetworkProcess::logFrameNavigation):
(WebKit::NetworkProcess::logUserInteraction):
* NetworkProcess/NetworkProcess.h:
* NetworkProcess/NetworkProcess.messages.in:
* NetworkProcess/NetworkSession.cpp:
(WebKit::NetworkSession::enableResourceLoadStatistics):
* NetworkProcess/NetworkSession.h:
(WebKit::NetworkSession::resourceLoadStatistics const):
* NetworkProcess/NetworkSessionCreationParameters.cpp:
(WebKit::NetworkSessionCreationParameters::privateSessionParameters):
(WebKit::NetworkSessionCreationParameters::encode const):
(WebKit::NetworkSessionCreationParameters::decode):
* NetworkProcess/NetworkSessionCreationParameters.h:
* NetworkProcess/cocoa/NetworkSessionCocoa.mm:
(WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::WebProcessPool::platformInitializeNetworkProcess):
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::didLogUserInteraction):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:
* UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
(WebsiteDataStore::parameters):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::decidePolicyForNavigationAction):
(WebKit::WebPageProxy::logFrameNavigation):
* UIProcess/WebPageProxy.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::ensureNetworkProcess):
(WebKit::WebProcessPool::initializeNewWebProcess):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@239816 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp
Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp
Source/WebKit/NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h
Source/WebKit/NetworkProcess/NetworkProcess.cpp
Source/WebKit/NetworkProcess/NetworkProcess.h
Source/WebKit/NetworkProcess/NetworkProcess.messages.in
Source/WebKit/NetworkProcess/NetworkSession.cpp
Source/WebKit/NetworkProcess/NetworkSession.h
Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.cpp
Source/WebKit/NetworkProcess/NetworkSessionCreationParameters.h
Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm
Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/WebProcessPool.cpp
Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm

index b999447..ba2e5f0 100644 (file)
@@ -1,3 +1,77 @@
+2019-01-09  Brent Fulgham  <bfulgham@apple.com>
+
+        Create a WebResourceLoadStatisticsStore attached to the NetworkSession
+        https://bugs.webkit.org/show_bug.cgi?id=193261
+        <rdar://problem/47158616>
+
+        Reviewed by Alex Christensen.
+
+        This patch modifies NetworkSession so that it owns a WebResourceLoadStatisticsStore
+        object. This object is only created if the ResourceLoadStatistics feature is turned on.
+
+        The patch also modifies WebResourceLoadStatisticsStore so that it can be constructed
+        with an owning NetworkSession as an alternative to the current practice of using a
+        WebsiteDataStore object.
+
+        Two initial messages from the WebContent process are added (logFrameNavigation and
+        logUserNavigation) that notify the network process of these actions. Currently they
+        are called in addition the calls to the WebsiteDataStore object. These redundant calls
+        will be removed in a future patch.
+
+        This patch forces the ResourceLoadStatistics code in the NetworkSession to be off by
+        default, so there should be no change in behavior with this patch.
+
+        * NetworkProcess/Classifier/ResourceLoadStatisticsMemoryStore.cpp:
+        (WebKit::ResourceLoadStatisticsMemoryStore::updateClientSideCookiesAgeCap):
+        * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
+        (WebKit::WebResourceLoadStatisticsStore::hasStorageAccessForFrame):
+        (WebKit::WebResourceLoadStatisticsStore::callHasStorageAccessForFrameHandler):
+        (WebKit::WebResourceLoadStatisticsStore::grantStorageAccess):
+        (WebKit::WebResourceLoadStatisticsStore::callGrantStorageAccessHandler):
+        (WebKit::WebResourceLoadStatisticsStore::removeAllStorageAccess):
+        (WebKit::WebResourceLoadStatisticsStore::logFrameNavigation):
+        (WebKit::WebResourceLoadStatisticsStore::logUserInteraction):
+        (WebKit::WebResourceLoadStatisticsStore::setCacheMaxAgeCapForPrevalentResources):
+        (WebKit::WebResourceLoadStatisticsStore::setCacheMaxAgeCap):
+        (WebKit::WebResourceLoadStatisticsStore::updatePrevalentDomainsToBlockCookiesFor):
+        (WebKit::WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler):
+        (WebKit::WebResourceLoadStatisticsStore::removePrevalentDomains):
+        (WebKit::WebResourceLoadStatisticsStore::callRemoveDomainsHandler):
+        * NetworkProcess/Classifier/WebResourceLoadStatisticsStore.h:
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::initializeNetworkProcess):
+        (WebKit::NetworkProcess::logFrameNavigation):
+        (WebKit::NetworkProcess::logUserInteraction):
+        * NetworkProcess/NetworkProcess.h:
+        * NetworkProcess/NetworkProcess.messages.in:
+        * NetworkProcess/NetworkSession.cpp:
+        (WebKit::NetworkSession::enableResourceLoadStatistics):
+        * NetworkProcess/NetworkSession.h:
+        (WebKit::NetworkSession::resourceLoadStatistics const):
+        * NetworkProcess/NetworkSessionCreationParameters.cpp:
+        (WebKit::NetworkSessionCreationParameters::privateSessionParameters):
+        (WebKit::NetworkSessionCreationParameters::encode const):
+        (WebKit::NetworkSessionCreationParameters::decode):
+        * NetworkProcess/NetworkSessionCreationParameters.h:
+        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
+        (WebKit::NetworkSessionCocoa::NetworkSessionCocoa):
+        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+        (WebKit::WebProcessPool::platformInitializeNetworkProcess):
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::didLogUserInteraction):
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
+        (WebsiteDataStore::parameters):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::decidePolicyForNavigationAction):
+        (WebKit::WebPageProxy::logFrameNavigation):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::ensureNetworkProcess):
+        (WebKit::WebProcessPool::initializeNewWebProcess):
+
 2019-01-09  Alex Christensen  <achristensen@webkit.org>
 
         Replace SessionTracker with HashMap member of NetworkProcess
index 19c38e1..8d62d68 100644 (file)
@@ -27,6 +27,7 @@
 #include "ResourceLoadStatisticsMemoryStore.h"
 
 #include "Logging.h"
+#include "NetworkSession.h"
 #include "PluginProcessManager.h"
 #include "PluginProcessProxy.h"
 #include "ResourceLoadStatisticsPersistentStorage.h"
@@ -34,6 +35,7 @@
 #include "WebResourceLoadStatisticsTelemetry.h"
 #include "WebsiteDataStore.h"
 #include <WebCore/KeyedCoding.h>
+#include <WebCore/NetworkStorageSession.h>
 #include <WebCore/ResourceLoadStatistics.h>
 #include <wtf/CallbackAggregator.h>
 #include <wtf/DateMath.h>
@@ -862,6 +864,8 @@ void ResourceLoadStatisticsMemoryStore::updateClientSideCookiesAgeCap()
     RunLoop::main().dispatch([store = makeRef(m_store), seconds = m_parameters.clientSideCookiesAgeCapTime] () {
         if (auto* websiteDataStore = store->websiteDataStore())
             websiteDataStore->setAgeCapForClientSideCookies(seconds, [] { });
+        if (auto* networkSession = store->networkSession())
+            networkSession->networkStorageSession().setAgeCapForClientSideCookies(seconds);
     });
 #endif
 }
index 451e710..f2d2973 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
@@ -27,6 +27,7 @@
 #include "WebResourceLoadStatisticsStore.h"
 
 #include "Logging.h"
+#include "NetworkSession.h"
 #include "ResourceLoadStatisticsMemoryStore.h"
 #include "ResourceLoadStatisticsPersistentStorage.h"
 #include "WebFrameProxy.h"
@@ -37,6 +38,7 @@
 #include "WebResourceLoadStatisticsTelemetry.h"
 #include "WebsiteDataFetchOption.h"
 #include "WebsiteDataStore.h"
+#include <WebCore/NetworkStorageSession.h>
 #include <WebCore/ResourceLoadStatistics.h>
 #include <wtf/CallbackAggregator.h>
 #include <wtf/CrossThreadCopier.h>
@@ -121,6 +123,21 @@ WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(WebsiteDataStore&
     m_dailyTasksTimer.startRepeating(24_h);
 }
 
+WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(NetworkSession& networkSession, const String& resourceLoadStatisticsDirectory)
+    : m_networkSession(makeWeakPtr(networkSession))
+    , m_statisticsQueue(WorkQueue::create("WebResourceLoadStatisticsStore Process Data Queue", WorkQueue::Type::Serial, WorkQueue::QOS::Utility))
+    , m_dailyTasksTimer(RunLoop::main(), this, &WebResourceLoadStatisticsStore::performDailyTasks)
+{
+    ASSERT(RunLoop::isMain());
+    
+    postTask([this, resourceLoadStatisticsDirectory = resourceLoadStatisticsDirectory.isolatedCopy()] {
+        m_memoryStore = std::make_unique<ResourceLoadStatisticsMemoryStore>(*this, m_statisticsQueue);
+        m_persistentStorage = std::make_unique<ResourceLoadStatisticsPersistentStorage>(*m_memoryStore, m_statisticsQueue, resourceLoadStatisticsDirectory);
+    });
+    
+    m_dailyTasksTimer.startRepeating(24_h);
+}
+
 WebResourceLoadStatisticsStore::~WebResourceLoadStatisticsStore()
 {
     ASSERT(RunLoop::isMain());
@@ -236,6 +253,13 @@ void WebResourceLoadStatisticsStore::hasStorageAccess(String&& subFrameHost, Str
     });
 }
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+bool WebResourceLoadStatisticsStore::hasStorageAccessForFrame(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID)
+{
+    return m_networkSession ? m_networkSession->networkStorageSession().hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID) : false;
+}
+#endif
+
 void WebResourceLoadStatisticsStore::callHasStorageAccessForFrameHandler(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool hasAccess)>&& callback)
 {
     ASSERT(RunLoop::isMain());
@@ -244,6 +268,9 @@ void WebResourceLoadStatisticsStore::callHasStorageAccessForFrameHandler(const S
     if (m_websiteDataStore) {
         m_websiteDataStore->hasStorageAccessForFrameHandler(resourceDomain, firstPartyDomain, frameID, pageID, WTFMove(callback));
         return;
+    } else {
+        callback(hasStorageAccessForFrame(resourceDomain, firstPartyDomain, frameID, pageID));
+        return;
     }
 #endif
     callback(false);
@@ -309,6 +336,21 @@ void WebResourceLoadStatisticsStore::grantStorageAccess(String&& subFrameHost, S
     });
 }
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+bool WebResourceLoadStatisticsStore::grantStorageAccess(const String& resourceDomain, const String& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID)
+{
+    bool isStorageGranted = false;
+
+    if (m_networkSession) {
+        m_networkSession->networkStorageSession().grantStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID);
+        ASSERT(m_networkSession->networkStorageSession().hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID));
+        isStorageGranted = true;
+    }
+
+    return isStorageGranted;
+}
+#endif
+
 void WebResourceLoadStatisticsStore::callGrantStorageAccessHandler(const String& subFramePrimaryDomain, const String& topFramePrimaryDomain, Optional<uint64_t> frameID, uint64_t pageID, CompletionHandler<void(bool)>&& callback)
 {
     ASSERT(RunLoop::isMain());
@@ -317,6 +359,9 @@ void WebResourceLoadStatisticsStore::callGrantStorageAccessHandler(const String&
     if (m_websiteDataStore) {
         m_websiteDataStore->grantStorageAccessHandler(subFramePrimaryDomain, topFramePrimaryDomain, frameID, pageID, WTFMove(callback));
         return;
+    } else {
+        callback(grantStorageAccess(subFramePrimaryDomain, topFramePrimaryDomain, frameID, pageID));
+        return;
     }
 #endif
     callback(false);
@@ -333,18 +378,26 @@ void WebResourceLoadStatisticsStore::didCreateNetworkProcess()
     });
 }
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+void WebResourceLoadStatisticsStore::removeAllStorageAccess()
+{
+    if (m_networkSession)
+        m_networkSession->networkStorageSession().removeAllStorageAccess();
+}
+#endif
+
 void WebResourceLoadStatisticsStore::removeAllStorageAccess(CompletionHandler<void()>&& completionHandler)
 {
     ASSERT(RunLoop::isMain());
 
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
-    if (m_websiteDataStore)
+    if (m_websiteDataStore) {
         m_websiteDataStore->removeAllStorageAccessHandler(WTFMove(completionHandler));
-    else
-        completionHandler();
-#else
-    completionHandler();
+        return;
+    }
+    removeAllStorageAccess();
 #endif
+    completionHandler();
 }
 
 void WebResourceLoadStatisticsStore::applicationWillTerminate()
@@ -402,7 +455,12 @@ void WebResourceLoadStatisticsStore::logFrameNavigation(const WebFrameProxy& fra
     auto mainFramePrimaryDomain = ResourceLoadStatistics::primaryDomain(pageURL);
     auto sourcePrimaryDomain = ResourceLoadStatistics::primaryDomain(sourceURL);
 
-    postTask([this, targetPrimaryDomain = targetPrimaryDomain.isolatedCopy(), mainFramePrimaryDomain = mainFramePrimaryDomain.isolatedCopy(), sourcePrimaryDomain = sourcePrimaryDomain.isolatedCopy(), targetHost = targetHost.toString().isolatedCopy(), mainFrameHost = mainFrameHost.toString().isolatedCopy(), isRedirect, isMainFrame = frame.isMainFrame()] {
+    logFrameNavigation(targetPrimaryDomain, mainFramePrimaryDomain, sourcePrimaryDomain, targetHost.toString(), mainFrameHost.toString(), isRedirect, frame.isMainFrame());
+}
+
+void WebResourceLoadStatisticsStore::logFrameNavigation(const String& targetPrimaryDomain, const String& mainFramePrimaryDomain, const String& sourcePrimaryDomain, const String& targetHost, const String& mainFrameHost, bool isRedirect, bool isMainFrame)
+{
+    postTask([this, targetPrimaryDomain = targetPrimaryDomain.isolatedCopy(), mainFramePrimaryDomain = mainFramePrimaryDomain.isolatedCopy(), sourcePrimaryDomain = sourcePrimaryDomain.isolatedCopy(), targetHost = targetHost.isolatedCopy(), mainFrameHost = mainFrameHost.isolatedCopy(), isRedirect, isMainFrame] {
         
         if (m_memoryStore)
             m_memoryStore->logFrameNavigation(targetPrimaryDomain, mainFramePrimaryDomain, sourcePrimaryDomain, targetHost, mainFrameHost, isRedirect, isMainFrame);
@@ -418,7 +476,14 @@ void WebResourceLoadStatisticsStore::logUserInteraction(const URL& url, Completi
         return;
     }
 
-    postTask([this, primaryDomain = isolatedPrimaryDomain(url), completionHandler = WTFMove(completionHandler)]() mutable {
+    logUserInteraction(isolatedPrimaryDomain(url), WTFMove(completionHandler));
+}
+
+void WebResourceLoadStatisticsStore::logUserInteraction(const String& targetPrimaryDomain, CompletionHandler<void()>&& completionHandler)
+{
+    ASSERT(RunLoop::isMain());
+
+    postTask([this, primaryDomain = targetPrimaryDomain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
         if (m_memoryStore)
             m_memoryStore->logUserInteraction(primaryDomain);
         postTaskReply(WTFMove(completionHandler));
@@ -823,6 +888,14 @@ void WebResourceLoadStatisticsStore::setGrandfatheringTime(Seconds seconds)
     });
 }
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+void WebResourceLoadStatisticsStore::setCacheMaxAgeCapForPrevalentResources(Seconds seconds)
+{
+    if (m_networkSession)
+        m_networkSession->networkStorageSession().setCacheMaxAgeCapForPrevalentResources(seconds);
+}
+#endif
+
 void WebResourceLoadStatisticsStore::setCacheMaxAgeCap(Seconds seconds, CompletionHandler<void()>&& completionHandler)
 {
     ASSERT(RunLoop::isMain());
@@ -833,10 +906,19 @@ void WebResourceLoadStatisticsStore::setCacheMaxAgeCap(Seconds seconds, Completi
         m_websiteDataStore->setCacheMaxAgeCapForPrevalentResources(seconds, WTFMove(completionHandler));
         return;
     }
+    setCacheMaxAgeCapForPrevalentResources(seconds);
 #endif
     completionHandler();
 }
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+void WebResourceLoadStatisticsStore::updatePrevalentDomainsToBlockCookiesFor(const Vector<String>& domainsToBlock)
+{
+    if (m_networkSession)
+        m_networkSession->networkStorageSession().setPrevalentDomainsToBlockCookiesFor(domainsToBlock);
+}
+#endif
+
 void WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler(const Vector<String>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
 {
     ASSERT(RunLoop::isMain());
@@ -846,10 +928,19 @@ void WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesFor
         m_websiteDataStore->updatePrevalentDomainsToBlockCookiesFor(domainsToBlock, WTFMove(completionHandler));
         return;
     }
+    updatePrevalentDomainsToBlockCookiesFor(domainsToBlock);
 #endif
     completionHandler();
 }
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+void WebResourceLoadStatisticsStore::removePrevalentDomains(const Vector<String>& domains)
+{
+    if (m_networkSession)
+        m_networkSession->networkStorageSession().removePrevalentDomains(domains);
+}
+#endif
+
 void WebResourceLoadStatisticsStore::callRemoveDomainsHandler(const Vector<String>& domains)
 {
     ASSERT(RunLoop::isMain());
@@ -857,6 +948,7 @@ void WebResourceLoadStatisticsStore::callRemoveDomainsHandler(const Vector<Strin
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
     if (m_websiteDataStore)
         m_websiteDataStore->removePrevalentDomains(domains);
+    removePrevalentDomains(domains);
 #endif
 }
     
index 581704a..00236a3 100644 (file)
@@ -46,6 +46,7 @@ struct ResourceLoadStatistics;
 
 namespace WebKit {
 
+class NetworkSession;
 class ResourceLoadStatisticsMemoryStore;
 class ResourceLoadStatisticsPersistentStorage;
 class WebFrameProxy;
@@ -65,6 +66,11 @@ public:
         return adoptRef(*new WebResourceLoadStatisticsStore(websiteDataStore));
     }
 
+    static Ref<WebResourceLoadStatisticsStore> create(NetworkSession& networkSession, const String& resourceLoadStatisticsDirectory)
+    {
+        return adoptRef(*new WebResourceLoadStatisticsStore(networkSession, resourceLoadStatisticsDirectory));
+    }
+
     ~WebResourceLoadStatisticsStore();
 
     static const OptionSet<WebsiteDataType>& monitoredDataTypes();
@@ -83,9 +89,13 @@ public:
     void applicationWillTerminate();
 
     void logFrameNavigation(const WebFrameProxy&, const URL& pageURL, const WebCore::ResourceRequest&, const URL& redirectURL);
+    void logFrameNavigation(const String& targetPrimaryDomain, const String& mainFramePrimaryDomain, const String& sourcePrimaryDomain, const String& targetHost, const String& mainFrameHost, bool isRedirect, bool isMainFrame);
     void logUserInteraction(const URL&, CompletionHandler<void()>&&);
+    void logUserInteraction(const String& targetPrimaryDomain, CompletionHandler<void()>&&);
     void clearUserInteraction(const URL&, CompletionHandler<void()>&&);
+    bool grantStorageAccess(const String& resourceDomain, const String& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID);
     void hasHadUserInteraction(const URL&, CompletionHandler<void(bool)>&&);
+    bool hasStorageAccessForFrame(const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID);
     void setLastSeen(const URL&, Seconds, CompletionHandler<void()>&&);
     void setPrevalentResource(const URL&, CompletionHandler<void()>&&);
     void setVeryPrevalentResource(const URL&, CompletionHandler<void()>&&);
@@ -98,6 +108,9 @@ public:
     void clearPrevalentResource(const URL&, CompletionHandler<void()>&&);
     void setGrandfathered(const URL&, bool);
     void isGrandfathered(const URL&, CompletionHandler<void(bool)>&&);
+    void removeAllStorageAccess();
+    void removePrevalentDomains(const Vector<String>& domainsToBlock);
+    void setCacheMaxAgeCapForPrevalentResources(Seconds);
     void setSubframeUnderTopFrameOrigin(const URL& subframe, const URL& topFrame);
     void setSubresourceUnderTopFrameOrigin(const URL& subresource, const URL& topFrame);
     void setSubresourceUniqueRedirectTo(const URL& subresource, const URL& hostNameRedirectedTo);
@@ -109,6 +122,7 @@ public:
     void scheduleClearBlockingStateForDomains(const Vector<String>& domains, CompletionHandler<void()>&&);
     void scheduleStatisticsAndDataRecordsProcessing();
     void submitTelemetry();
+    void updatePrevalentDomainsToBlockCookiesFor(const Vector<String>& domainsToBlock);
 
     enum class ShouldGrandfather {
         No,
@@ -140,9 +154,11 @@ public:
     void didCreateNetworkProcess();
 
     WebsiteDataStore* websiteDataStore() { return m_websiteDataStore.get(); }
+    NetworkSession* networkSession() { return m_networkSession.get(); }
 
 private:
     explicit WebResourceLoadStatisticsStore(WebsiteDataStore&);
+    explicit WebResourceLoadStatisticsStore(NetworkSession&, const String&);
 
     void postTask(WTF::Function<void()>&&);
     static void postTaskReply(WTF::Function<void()>&&);
@@ -161,6 +177,7 @@ private:
     void flushAndDestroyPersistentStore();
 
     WeakPtr<WebsiteDataStore> m_websiteDataStore;
+    WeakPtr<NetworkSession> m_networkSession;
     Ref<WorkQueue> m_statisticsQueue;
     std::unique_ptr<ResourceLoadStatisticsMemoryStore> m_memoryStore;
     std::unique_ptr<ResourceLoadStatisticsPersistentStorage> m_persistentStorage;
index 36471de..41a5811 100644 (file)
@@ -53,6 +53,7 @@
 #include "WebCookieManager.h"
 #include "WebPageProxyMessages.h"
 #include "WebProcessPoolMessages.h"
+#include "WebResourceLoadStatisticsStore.h"
 #include "WebSWOriginStore.h"
 #include "WebSWServerConnection.h"
 #include "WebSWServerToContextConnection.h"
@@ -300,6 +301,8 @@ void NetworkProcess::initializeNetworkProcess(NetworkProcessCreationParameters&&
     if (parameters.shouldUseTestingNetworkSession)
         NetworkStorageSession::switchToNewTestingSession();
 
+    SandboxExtension::consumePermanently(parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectoryExtensionHandle);
+
     auto sessionID = parameters.defaultDataStoreParameters.networkSessionParameters.sessionID;
     setSession(sessionID, NetworkSession::create(*this, WTFMove(parameters.defaultDataStoreParameters.networkSessionParameters)));
 
@@ -534,6 +537,27 @@ void NetworkProcess::grantStorageAccess(PAL::SessionID sessionID, const String&
     parentProcessConnection()->send(Messages::NetworkProcessProxy::StorageAccessRequestResult(isStorageGranted, contextId), 0);
 }
 
+void NetworkProcess::logFrameNavigation(PAL::SessionID sessionID, const String& targetPrimaryDomain, const String& mainFramePrimaryDomain, const String& sourcePrimaryDomain, const String& targetHost, const String& mainFrameHost, bool isRedirect, bool isMainFrame)
+{
+    if (auto* networkSession = SessionTracker::networkSession(sessionID)) {
+        if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics())
+            resourceLoadStatistics->logFrameNavigation(targetPrimaryDomain, mainFramePrimaryDomain, sourcePrimaryDomain, targetHost, mainFrameHost, isRedirect, isMainFrame);
+    } else
+        ASSERT_NOT_REACHED();
+}
+
+void NetworkProcess::logUserInteraction(PAL::SessionID sessionID, const String& targetPrimaryDomain, uint64_t contextId)
+{
+    if (auto* networkSession = SessionTracker::networkSession(sessionID)) {
+        if (auto* resourceLoadStatistics = networkSession->resourceLoadStatistics()) {
+            resourceLoadStatistics->logUserInteraction(targetPrimaryDomain, [this, contextId] {
+                parentProcessConnection()->send(Messages::NetworkProcessProxy::DidLogUserInteraction(contextId), 0);
+            });        
+        }
+    } else
+        ASSERT_NOT_REACHED();
+}
+
 void NetworkProcess::removeAllStorageAccess(PAL::SessionID sessionID, uint64_t contextId)
 {
     if (auto* networkStorageSession = NetworkStorageSession::storageSession(sessionID))
index 8627d91..a8a5124 100644 (file)
@@ -161,6 +161,8 @@ public:
     void hasStorageAccessForFrame(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId);
     void getAllStorageAccessEntries(PAL::SessionID, uint64_t contextId);
     void grantStorageAccess(PAL::SessionID, const String& resourceDomain, const String& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID, uint64_t contextId);
+    void logFrameNavigation(PAL::SessionID, const String& targetPrimaryDomain, const String& mainFramePrimaryDomain, const String& sourcePrimaryDomain, const String& targetHost, const String& mainFrameHost, bool isRedirect, bool isMainFrame);
+    void logUserInteraction(PAL::SessionID, const String& targetPrimaryDomain, uint64_t contextId);
     void removeAllStorageAccess(PAL::SessionID, uint64_t contextId);
     void removePrevalentDomains(PAL::SessionID, const Vector<String>& domains);
     void setCacheMaxAgeCapForPrevalentResources(PAL::SessionID, Seconds, uint64_t contextId);
index 8d87224..8ba1675 100644 (file)
@@ -90,6 +90,8 @@ messages -> NetworkProcess LegacyReceiver {
     HasStorageAccessForFrame(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, uint64_t frameID, uint64_t pageID, uint64_t contextId)
     GetAllStorageAccessEntries(PAL::SessionID sessionID, uint64_t contextId)
     GrantStorageAccess(PAL::SessionID sessionID, String resourceDomain, String firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID, uint64_t contextId)
+    LogFrameNavigation(PAL::SessionID sessionID, String targetPrimaryDomain, String mainFramePrimaryDomain, String sourcePrimaryDomain, String targetHost, String mainFrameHost, bool isRedirect, bool isMainFrame)
+    LogUserInteraction(PAL::SessionID sessionID, String targetPrimaryDomain, uint64_t contextId)
     RemoveAllStorageAccess(PAL::SessionID sessionID, uint64_t contextId)
     RemovePrevalentDomains(PAL::SessionID sessionID, Vector<String> domainsWithInteraction)
     SetCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, Seconds seconds, uint64_t contextId)
index 5ba5c1c..820546d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-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
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "NetworkSession.h"
 
+#include "WebResourceLoadStatisticsStore.h"
 #include <WebCore/NetworkStorageSession.h>
 
 #if PLATFORM(COCOA)
@@ -77,4 +78,12 @@ void NetworkSession::invalidateAndCancel()
         task->invalidateAndCancel();
 }
 
+void NetworkSession::enableResourceLoadStatistics()
+{
+    if (m_resourceLoadStatistics)
+        return;
+
+    m_resourceLoadStatistics = WebResourceLoadStatisticsStore::create(*this, m_resourceLoadStatisticsDirectory);
+}
+
 } // namespace WebKit
index c0487da..4292db7 100644 (file)
@@ -30,6 +30,8 @@
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
 #include <wtf/Seconds.h>
+#include <wtf/WeakPtr.h>
+#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 class NetworkStorageSession;
@@ -39,9 +41,10 @@ namespace WebKit {
 
 class NetworkDataTask;
 class NetworkProcess;
+class WebResourceLoadStatisticsStore;
 struct NetworkSessionCreationParameters;
 
-class NetworkSession : public RefCounted<NetworkSession> {
+class NetworkSession : public RefCounted<NetworkSession>, public CanMakeWeakPtr<NetworkSession> {
 public:
     static Ref<NetworkSession> create(NetworkProcess&, NetworkSessionCreationParameters&&);
     virtual ~NetworkSession();
@@ -58,12 +61,17 @@ public:
     void registerNetworkDataTask(NetworkDataTask& task) { m_dataTaskSet.add(&task); }
     void unregisterNetworkDataTask(NetworkDataTask& task) { m_dataTaskSet.remove(&task); }
 
+    WebResourceLoadStatisticsStore* resourceLoadStatistics() const { return m_resourceLoadStatistics.get(); }
+    void enableResourceLoadStatistics();
+    
 protected:
     NetworkSession(NetworkProcess&, PAL::SessionID);
 
     PAL::SessionID m_sessionID;
     Ref<NetworkProcess> m_networkProcess;
     HashSet<NetworkDataTask*> m_dataTaskSet;
+    String m_resourceLoadStatisticsDirectory;
+    RefPtr<WebResourceLoadStatisticsStore> m_resourceLoadStatistics;
 };
 
 } // namespace WebKit
index 5d6454c..270ae43 100644 (file)
@@ -47,6 +47,7 @@ NetworkSessionCreationParameters NetworkSessionCreationParameters::privateSessio
 #if USE(CURL)
         , { }, { }
 #endif
+        , { }, { }, false
     };
 }
 
@@ -68,6 +69,9 @@ void NetworkSessionCreationParameters::encode(IPC::Encoder& encoder) const
     encoder << cookiePersistentStorageFile;
     encoder << proxySettings;
 #endif
+    encoder << resourceLoadStatisticsDirectory;
+    encoder << resourceLoadStatisticsDirectoryExtensionHandle;
+    encoder << enableResourceLoadStatistics;
 }
 
 Optional<NetworkSessionCreationParameters> NetworkSessionCreationParameters::decode(IPC::Decoder& decoder)
@@ -133,7 +137,22 @@ Optional<NetworkSessionCreationParameters> NetworkSessionCreationParameters::dec
     if (!proxySettings)
         return WTF::nullopt;
 #endif
-    
+
+    Optional<String> resourceLoadStatisticsDirectory;
+    decoder >> resourceLoadStatisticsDirectory;
+    if (!resourceLoadStatisticsDirectory)
+        return WTF::nullopt;
+
+    Optional<SandboxExtension::Handle> resourceLoadStatisticsDirectoryExtensionHandle;
+    decoder >> resourceLoadStatisticsDirectoryExtensionHandle;
+    if (!resourceLoadStatisticsDirectoryExtensionHandle)
+        return WTF::nullopt;
+
+    Optional<bool> enableResourceLoadStatistics;
+    decoder >> enableResourceLoadStatistics;
+    if (!enableResourceLoadStatistics)
+        return WTF::nullopt;
+
     return {{
         sessionID
         , WTFMove(*boundInterfaceIdentifier)
@@ -151,6 +170,9 @@ Optional<NetworkSessionCreationParameters> NetworkSessionCreationParameters::dec
         , WTFMove(*cookiePersistentStorageFile)
         , WTFMove(*proxySettings)
 #endif
+        , WTFMove(*resourceLoadStatisticsDirectory)
+        , WTFMove(*resourceLoadStatisticsDirectoryExtensionHandle)
+        , WTFMove(*enableResourceLoadStatistics)
     }};
 }
 
index 09af333..6f9de8b 100644 (file)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "SandboxExtension.h"
 #include <pal/SessionID.h>
 #include <wtf/Seconds.h>
 #include <wtf/URL.h>
@@ -69,6 +70,9 @@ struct NetworkSessionCreationParameters {
     String cookiePersistentStorageFile;
     WebCore::CurlProxySettings proxySettings;
 #endif
+    String resourceLoadStatisticsDirectory;
+    SandboxExtension::Handle resourceLoadStatisticsDirectoryExtensionHandle;
+    bool enableResourceLoadStatistics { false };
 };
 
 } // namespace WebKit
index 25a6451..4404dac 100644 (file)
@@ -931,6 +931,10 @@ NetworkSessionCocoa::NetworkSessionCocoa(NetworkProcess& networkProcess, Network
 
     m_statelessSessionDelegate = adoptNS([[WKNetworkSessionDelegate alloc] initWithNetworkSession:*this withCredentials:false]);
     m_statelessSession = [NSURLSession sessionWithConfiguration:configuration delegate:static_cast<id>(m_statelessSessionDelegate.get()) delegateQueue:[NSOperationQueue mainQueue]];
+
+    m_resourceLoadStatisticsDirectory = parameters.resourceLoadStatisticsDirectory;
+    if (parameters.enableResourceLoadStatistics)
+        enableResourceLoadStatistics();
 }
 
 NetworkSessionCocoa::~NetworkSessionCocoa()
index 4a791f3..d4d3204 100644 (file)
@@ -419,6 +419,12 @@ void NetworkProcessProxy::didUpdateBlockCookies(uint64_t callbackId)
     m_updateBlockCookiesCallbackMap.take(callbackId)();
 }
 
+void NetworkProcessProxy::didLogUserInteraction(uint64_t contextId)
+{
+    // FIXME(193297): Implement when activating automated test cases.
+    UNUSED_PARAM(contextId);
+}
+
 void NetworkProcessProxy::setAgeCapForClientSideCookies(PAL::SessionID sessionID, Optional<Seconds> seconds, CompletionHandler<void()>&& completionHandler)
 {
     if (!canSendMessage()) {
index 4fe5ce7..e348a85 100644 (file)
@@ -142,6 +142,7 @@ private:
     void logDiagnosticMessageWithResult(uint64_t pageID, const String& message, const String& description, uint32_t result, WebCore::ShouldSample);
     void logDiagnosticMessageWithValue(uint64_t pageID, const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample);
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
+    void didLogUserInteraction(uint64_t contextId);
     void didUpdateBlockCookies(uint64_t contextId);
     void didSetAgeCapForClientSideCookies(uint64_t contextId);
     void storageAccessRequestResult(bool wasGranted, uint64_t contextId);
index b5641f9..2aae3eb 100644 (file)
@@ -40,6 +40,7 @@ messages -> NetworkProcessProxy LegacyReceiver {
     LogDiagnosticMessageWithValue(uint64_t pageID, String message, String description, double value, unsigned significantFigures, enum:bool WebCore::ShouldSample shouldSample)
 
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
+    DidLogUserInteraction(uint64_t callbackId)
     DidUpdateBlockCookies(uint64_t callbackId)
     DidSetAgeCapForClientSideCookies(uint64_t callbackId)
     StorageAccessRequestResult(bool wasGranted, uint64_t contextId)
index 5e88479..392743b 100644 (file)
 #include "WebAuthenticatorCoordinatorProxy.h"
 #endif
 
-#if ENABLE(RESOURCE_LOAD_STATISTICS)
-#include "WebResourceLoadStatisticsStore.h"
-#endif
-
 #if ENABLE(REMOTE_INSPECTOR)
 #include <JavaScriptCore/RemoteInspector.h>
 #endif
@@ -4451,8 +4447,11 @@ void WebPageProxy::decidePolicyForNavigationAction(WebFrameProxy& frame, WebCore
     API::Navigation* mainFrameNavigation = frame.isMainFrame() ? navigation.get() : nullptr;
     WebFrameProxy* originatingFrame = m_process->webFrame(originatingFrameInfoData.frameID);
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
     if (auto* resourceLoadStatisticsStore = websiteDataStore().resourceLoadStatistics())
         resourceLoadStatisticsStore->logFrameNavigation(frame, URL(URL(), m_pageLoadState.url()), request, redirectResponse.url());
+    logFrameNavigation(frame, URL(URL(), m_pageLoadState.url()), request, redirectResponse.url());
+#endif
 
     if (m_policyClient)
         m_policyClient->decidePolicyForNavigationAction(*this, &frame, WTFMove(navigationActionData), originatingFrame, originalRequest, WTFMove(request), WTFMove(listener), m_process->transformHandlesToObjects(userData.object()).get());
@@ -4475,6 +4474,38 @@ void WebPageProxy::decidePolicyForNavigationAction(WebFrameProxy& frame, WebCore
     m_shouldSuppressAppLinksInNextNavigationPolicyDecision = false;
 }
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+void WebPageProxy::logFrameNavigation(const WebFrameProxy& frame, const URL& pageURL, const WebCore::ResourceRequest& request, const URL& redirectURL)
+{
+    ASSERT(RunLoop::isMain());
+    
+    auto sourceURL = redirectURL;
+    bool isRedirect = !redirectURL.isNull();
+    if (!isRedirect) {
+        sourceURL = frame.url();
+        if (sourceURL.isNull())
+            sourceURL = pageURL;
+    }
+    
+    auto& targetURL = request.url();
+    
+    if (!targetURL.isValid() || !pageURL.isValid())
+        return;
+    
+    auto targetHost = targetURL.host();
+    auto mainFrameHost = pageURL.host();
+    
+    if (targetHost.isEmpty() || mainFrameHost.isEmpty() || targetHost == sourceURL.host())
+        return;
+    
+    auto targetPrimaryDomain = ResourceLoadStatistics::primaryDomain(targetURL);
+    auto mainFramePrimaryDomain = ResourceLoadStatistics::primaryDomain(pageURL);
+    auto sourcePrimaryDomain = ResourceLoadStatistics::primaryDomain(sourceURL);
+
+    m_process->processPool().sendToNetworkingProcess(Messages::NetworkProcess::LogFrameNavigation(m_websiteDataStore->sessionID(), targetPrimaryDomain, mainFramePrimaryDomain, sourcePrimaryDomain, targetHost.toString(), mainFrameHost.toString(), isRedirect, frame.isMainFrame()));
+}
+#endif
+
 void WebPageProxy::decidePolicyForNavigationActionSync(uint64_t frameID, bool isMainFrame, WebCore::SecurityOriginData&& frameSecurityOrigin, uint64_t navigationID, NavigationActionData&& navigationActionData, FrameInfoData&& frameInfoData, uint64_t originatingPageID, const WebCore::ResourceRequest& originalRequest, WebCore::ResourceRequest&& request, IPC::FormDataReference&& requestBody, WebCore::ResourceResponse&& redirectResponse, const UserData& userData, Messages::WebPageProxy::DecidePolicyForNavigationActionSync::DelayedReply&& reply)
 {
     auto sender = PolicyDecisionSender::create(WTFMove(reply));
index 210ddb8..cd801b8 100644 (file)
@@ -1907,6 +1907,10 @@ private:
     void setNeedsFontAttributes(bool);
     void updateFontAttributesAfterEditorStateChange();
 
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+    void logFrameNavigation(const WebFrameProxy&, const URL& pageURL, const WebCore::ResourceRequest&, const URL& redirectURL);
+#endif
+
     WeakPtr<PageClient> m_pageClient;
     Ref<API::PageConfiguration> m_configuration;
 
index 2578d3c..3f1406e 100644 (file)
@@ -548,6 +548,15 @@ NetworkProcessProxy& WebProcessPool::ensureNetworkProcess(WebsiteDataStore* with
     parameters.shouldDisableServiceWorkerProcessTerminationDelay = m_shouldDisableServiceWorkerProcessTerminationDelay;
 #endif
 
+    if (m_websiteDataStore)
+        parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectory = m_websiteDataStore->websiteDataStore().resolvedResourceLoadStatisticsDirectory();
+    if (parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectory.isEmpty())
+        parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectory = API::WebsiteDataStore::defaultResourceLoadStatisticsDirectory();
+
+    SandboxExtension::createHandleForReadWriteDirectory(parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectory, parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectoryExtensionHandle);
+
+    parameters.defaultDataStoreParameters.networkSessionParameters.enableResourceLoadStatistics = false; // FIXME(193297): Turn on when the feature is on.
+
     // Add any platform specific parameters
     platformInitializeNetworkProcess(parameters);
 
index 877edd4..069d4b9 100644 (file)
@@ -83,6 +83,11 @@ WebsiteDataStoreParameters WebsiteDataStore::parameters()
     if (!httpsProxy.isValid() && isSafari)
         httpsProxy = URL(URL(), [defaults stringForKey:(NSString *)WebKit2HTTPSProxyDefaultsKey]);
 
+    auto resourceLoadStatisticsDirectory = m_configuration->resourceLoadStatisticsDirectory();
+    SandboxExtension::Handle resourceLoadStatisticsDirectoryHandle;
+    if (!resourceLoadStatisticsDirectory.isEmpty())
+        SandboxExtension::createHandleForReadWriteDirectory(resourceLoadStatisticsDirectory, resourceLoadStatisticsDirectoryHandle);
+
     WebsiteDataStoreParameters parameters;
     parameters.networkSessionParameters = {
         m_sessionID,
@@ -95,6 +100,9 @@ WebsiteDataStoreParameters WebsiteDataStore::parameters()
         Seconds { [defaults integerForKey:WebKitNetworkLoadThrottleLatencyMillisecondsDefaultsKey] / 1000. },
         WTFMove(httpProxy),
         WTFMove(httpsProxy),
+        WTFMove(resourceLoadStatisticsDirectory),
+        WTFMove(resourceLoadStatisticsDirectoryHandle),
+        false // FIXME(193297): Switch to m_configuration->resourceLoadStatisticsEnabled()
     };
 
     auto cookieFile = resolvedCookieStorageFile();