Adopt WebCore::RegistrableDomain in WebCore::ResourceLoadStatistics and WebKit::Netwo...
[WebKit-https.git] / Source / WebKit / NetworkProcess / Classifier / WebResourceLoadStatisticsStore.cpp
1 /*
2  * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebResourceLoadStatisticsStore.h"
28
29 #if ENABLE(RESOURCE_LOAD_STATISTICS)
30
31 #include "APIDictionary.h"
32 #include "Logging.h"
33 #include "NetworkProcess.h"
34 #include "NetworkSession.h"
35 #include "ResourceLoadStatisticsMemoryStore.h"
36 #include "ResourceLoadStatisticsPersistentStorage.h"
37 #include "ShouldGrandfatherStatistics.h"
38 #include "StorageAccessStatus.h"
39 #include "WebFrameProxy.h"
40 #include "WebPageProxy.h"
41 #include "WebProcessMessages.h"
42 #include "WebProcessPool.h"
43 #include "WebProcessProxy.h"
44 #include "WebResourceLoadStatisticsStoreMessages.h"
45 #include "WebResourceLoadStatisticsTelemetry.h"
46 #include "WebsiteDataFetchOption.h"
47 #include <WebCore/DiagnosticLoggingClient.h>
48 #include <WebCore/DiagnosticLoggingKeys.h>
49 #include <WebCore/NetworkStorageSession.h>
50 #include <WebCore/ResourceLoadStatistics.h>
51 #include <wtf/CallbackAggregator.h>
52 #include <wtf/CrossThreadCopier.h>
53 #include <wtf/NeverDestroyed.h>
54 #include <wtf/threads/BinarySemaphore.h>
55
56 namespace WebKit {
57 using namespace WebCore;
58
59 const OptionSet<WebsiteDataType>& WebResourceLoadStatisticsStore::monitoredDataTypes()
60 {
61     static NeverDestroyed<OptionSet<WebsiteDataType>> dataTypes(std::initializer_list<WebsiteDataType>({
62         WebsiteDataType::Cookies,
63         WebsiteDataType::DOMCache,
64         WebsiteDataType::IndexedDBDatabases,
65         WebsiteDataType::LocalStorage,
66         WebsiteDataType::MediaKeys,
67         WebsiteDataType::OfflineWebApplicationCache,
68 #if ENABLE(NETSCAPE_PLUGIN_API)
69         WebsiteDataType::PlugInData,
70 #endif
71         WebsiteDataType::SearchFieldRecentSearches,
72         WebsiteDataType::SessionStorage,
73 #if ENABLE(SERVICE_WORKER)
74         WebsiteDataType::ServiceWorkerRegistrations,
75 #endif
76         WebsiteDataType::WebSQLDatabases,
77     }));
78
79     ASSERT(RunLoop::isMain());
80
81     return dataTypes;
82 }
83
84 void WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned(bool value)
85 {
86     ASSERT(RunLoop::isMain());
87
88     postTask([this, value] {
89         if (m_memoryStore)
90             m_memoryStore->setNotifyPagesWhenDataRecordsWereScanned(value);
91     });
92 }
93
94 void WebResourceLoadStatisticsStore::setNotifyPagesWhenDataRecordsWereScanned(bool value, CompletionHandler<void()>&& completionHandler)
95 {
96     ASSERT(RunLoop::isMain());
97     
98     postTask([this, value, completionHandler = WTFMove(completionHandler)]() mutable {
99         if (m_memoryStore)
100             m_memoryStore->setNotifyPagesWhenDataRecordsWereScanned(value);
101         
102         postTaskReply(WTFMove(completionHandler));
103     });
104 }
105
106 void WebResourceLoadStatisticsStore::setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value, CompletionHandler<void()>&& completionHandler)
107 {
108     ASSERT(RunLoop::isMain());
109
110     postTask([this, value, completionHandler = WTFMove(completionHandler)]() mutable {
111         if (m_memoryStore)
112             m_memoryStore->setShouldClassifyResourcesBeforeDataRecordsRemoval(value);
113
114         postTaskReply(WTFMove(completionHandler));
115     });
116 }
117
118 void WebResourceLoadStatisticsStore::setShouldSubmitTelemetry(bool value)
119 {
120     ASSERT(RunLoop::isMain());
121
122     postTask([this, value] {
123         if (m_memoryStore)
124             m_memoryStore->setShouldSubmitTelemetry(value);
125     });
126 }
127
128 void WebResourceLoadStatisticsStore::setNotifyPagesWhenTelemetryWasCaptured(bool value, CompletionHandler<void()>&& completionHandler)
129 {
130     ASSERT(RunLoop::isMain());
131
132     WebKit::WebResourceLoadStatisticsTelemetry::setNotifyPagesWhenTelemetryWasCaptured(value);
133     completionHandler();
134 }
135
136 WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(NetworkSession& networkSession, const String& resourceLoadStatisticsDirectory)
137     : m_networkSession(makeWeakPtr(networkSession))
138     , m_statisticsQueue(WorkQueue::create("WebResourceLoadStatisticsStore Process Data Queue", WorkQueue::Type::Serial, WorkQueue::QOS::Utility))
139     , m_dailyTasksTimer(RunLoop::main(), this, &WebResourceLoadStatisticsStore::performDailyTasks)
140 {
141     ASSERT(RunLoop::isMain());
142     
143     postTask([this, resourceLoadStatisticsDirectory = resourceLoadStatisticsDirectory.isolatedCopy()] {
144         m_memoryStore = std::make_unique<ResourceLoadStatisticsMemoryStore>(*this, m_statisticsQueue);
145         m_persistentStorage = std::make_unique<ResourceLoadStatisticsPersistentStorage>(*m_memoryStore, m_statisticsQueue, resourceLoadStatisticsDirectory);
146
147         // FIXME(193297): This should be revised after the UIProcess version goes away.
148         m_memoryStore->didCreateNetworkProcess();
149     });
150     
151     m_dailyTasksTimer.startRepeating(24_h);
152 }
153
154 WebResourceLoadStatisticsStore::~WebResourceLoadStatisticsStore()
155 {
156     ASSERT(RunLoop::isMain());
157
158     flushAndDestroyPersistentStore();
159 }
160
161 inline void WebResourceLoadStatisticsStore::postTask(WTF::Function<void()>&& task)
162 {
163     ASSERT(RunLoop::isMain());
164     m_statisticsQueue->dispatch([protectedThis = makeRef(*this), task = WTFMove(task)] {
165         task();
166     });
167 }
168
169 inline void WebResourceLoadStatisticsStore::postTaskReply(WTF::Function<void()>&& reply)
170 {
171     ASSERT(!RunLoop::isMain());
172     RunLoop::main().dispatch(WTFMove(reply));
173 }
174
175 void WebResourceLoadStatisticsStore::flushAndDestroyPersistentStore()
176 {
177     ASSERT(RunLoop::isMain());
178
179     if (!m_persistentStorage && !m_memoryStore)
180         return;
181
182     // Make sure we destroy the persistent store on the background queue and wait for it to die
183     // synchronously since it has a C++ reference to us. Blocking nature of this task allows us
184     // to not maintain a WebResourceLoadStatisticsStore reference for the duration of dispatch,
185     // avoiding double-deletion issues when this is invoked from the destructor.
186     BinarySemaphore semaphore;
187     m_statisticsQueue->dispatch([&semaphore, this] {
188         m_persistentStorage = nullptr;
189         m_memoryStore = nullptr;
190         semaphore.signal();
191     });
192     semaphore.wait();
193 }
194
195 void WebResourceLoadStatisticsStore::setResourceLoadStatisticsDebugMode(bool value, CompletionHandler<void()>&& completionHandler)
196 {
197     ASSERT(RunLoop::isMain());
198
199     postTask([this, value, completionHandler = WTFMove(completionHandler)]() mutable {
200         if (m_memoryStore)
201             m_memoryStore->setResourceLoadStatisticsDebugMode(value);
202         postTaskReply(WTFMove(completionHandler));
203     });
204 }
205
206 void WebResourceLoadStatisticsStore::setPrevalentResourceForDebugMode(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
207 {
208     ASSERT(RunLoop::isMain());
209     
210     postTask([this, domain = domain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
211         if (m_memoryStore)
212             m_memoryStore->setPrevalentResourceForDebugMode(domain);
213         postTaskReply(WTFMove(completionHandler));
214     });
215 }
216
217 void WebResourceLoadStatisticsStore::scheduleStatisticsAndDataRecordsProcessing(CompletionHandler<void()>&& completionHandler)
218 {
219     ASSERT(RunLoop::isMain());
220     
221     postTask([this, completionHandler = WTFMove(completionHandler)]() mutable {
222         if (m_memoryStore)
223             m_memoryStore->processStatisticsAndDataRecords();
224         postTaskReply(WTFMove(completionHandler));
225     });
226 }
227
228 void WebResourceLoadStatisticsStore::requestUpdate()
229 {
230     resourceLoadStatisticsUpdated({ });
231 }
232
233 void WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated(Vector<WebCore::ResourceLoadStatistics>&& origins)
234 {
235     ASSERT(RunLoop::isMain());
236
237     // It is safe to move the origins to the background queue without isolated copy here because this is an r-value
238     // coming from IPC. ResourceLoadStatistics only contains strings which are safe to move to other threads as long
239     // as nobody on this thread holds a reference to those strings.
240     postTask([this, origins = WTFMove(origins)]() mutable {
241         if (!m_memoryStore)
242             return;
243
244         m_memoryStore->mergeStatistics(WTFMove(origins));
245
246         // We can cancel any pending request to process statistics since we're doing it synchronously below.
247         m_memoryStore->cancelPendingStatisticsProcessingRequest();
248
249         // Fire before processing statistics to propagate user interaction as fast as possible to the network process.
250         m_memoryStore->updateCookieBlocking([]() { });
251         m_memoryStore->processStatisticsAndDataRecords();
252     });
253 }
254
255 void WebResourceLoadStatisticsStore::hasStorageAccess(const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, Optional<uint64_t> frameID, uint64_t pageID, CompletionHandler<void(bool)>&& completionHandler)
256 {
257     ASSERT(subFrameDomain != topFrameDomain);
258     ASSERT(RunLoop::isMain());
259
260     postTask([this, subFrameDomain = subFrameDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), frameID, pageID, completionHandler = WTFMove(completionHandler)]() mutable {
261         if (!m_memoryStore) {
262             postTaskReply([completionHandler = WTFMove(completionHandler)]() mutable {
263                 completionHandler(false);
264             });
265             return;
266         }
267         m_memoryStore->hasStorageAccess(subFrameDomain, topFrameDomain, frameID, pageID, [completionHandler = WTFMove(completionHandler)](bool hasStorageAccess) mutable {
268             postTaskReply([completionHandler = WTFMove(completionHandler), hasStorageAccess]() mutable {
269                 completionHandler(hasStorageAccess);
270             });
271         });
272     });
273 }
274
275 bool WebResourceLoadStatisticsStore::hasStorageAccessForFrame(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, uint64_t frameID, uint64_t pageID)
276 {
277     return m_networkSession ? m_networkSession->networkStorageSession().hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID) : false;
278 }
279
280 void WebResourceLoadStatisticsStore::callHasStorageAccessForFrameHandler(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool hasAccess)>&& callback)
281 {
282     ASSERT(RunLoop::isMain());
283
284     if (m_networkSession) {
285         callback(m_networkSession->networkStorageSession().hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID));
286         return;
287     }
288
289     callback(false);
290 }
291
292 void WebResourceLoadStatisticsStore::requestStorageAccessGranted(const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, uint64_t frameID, uint64_t pageID, bool promptEnabled, CompletionHandler<void(bool)>&& completionHandler)
293 {
294     auto statusHandler = [this, protectedThis = makeRef(*this), subFrameDomain = subFrameDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), promptEnabled, frameID, pageID, completionHandler = WTFMove(completionHandler)](StorageAccessStatus status) mutable {
295         switch (status) {
296         case StorageAccessStatus::CannotRequestAccess:
297             completionHandler(false);
298             return;
299         case StorageAccessStatus::RequiresUserPrompt:
300             {
301             ASSERT_UNUSED(promptEnabled, promptEnabled);
302             CompletionHandler<void(bool)> requestConfirmationCompletionHandler = [this, protectedThis = protectedThis.copyRef(), subFrameDomain, topFrameDomain, frameID, pageID, completionHandler = WTFMove(completionHandler)] (bool userDidGrantAccess) mutable {
303                 if (userDidGrantAccess)
304                     grantStorageAccess(subFrameDomain, topFrameDomain, frameID, pageID, userDidGrantAccess, WTFMove(completionHandler));
305                 else
306                     completionHandler(false);
307             };
308             m_networkSession->networkProcess().parentProcessConnection()->sendWithAsyncReply(Messages::NetworkProcessProxy::RequestStorageAccessConfirm(pageID, frameID, subFrameDomain, topFrameDomain), WTFMove(requestConfirmationCompletionHandler));
309             }
310             return;
311         case StorageAccessStatus::HasAccess:
312             completionHandler(true);
313             return;
314         }
315     };
316
317     requestStorageAccess(subFrameDomain, topFrameDomain, frameID, pageID, promptEnabled, WTFMove(statusHandler));
318 }
319
320 void WebResourceLoadStatisticsStore::requestStorageAccess(const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, Optional<uint64_t> frameID, uint64_t pageID, bool promptEnabled, CompletionHandler<void(StorageAccessStatus)>&& completionHandler)
321 {
322     if (subFrameDomain == topFrameDomain) {
323         completionHandler(StorageAccessStatus::HasAccess);
324         return;
325     }
326
327     postTask([this, subFrameDomain = subFrameDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), frameID, pageID, promptEnabled, completionHandler = WTFMove(completionHandler)]() mutable {
328         if (!m_memoryStore) {
329             postTaskReply([completionHandler = WTFMove(completionHandler)]() mutable {
330                 completionHandler(StorageAccessStatus::CannotRequestAccess);
331             });
332             return;
333         }
334
335         m_memoryStore->requestStorageAccess(WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID.value(), pageID, promptEnabled, [completionHandler = WTFMove(completionHandler)](StorageAccessStatus status) mutable {
336             postTaskReply([completionHandler = WTFMove(completionHandler), status]() mutable {
337                 completionHandler(status);
338             });
339         });
340     });
341 }
342
343 void WebResourceLoadStatisticsStore::requestStorageAccessUnderOpener(RegistrableDomain&& domainInNeedOfStorageAccess, uint64_t openerPageID, RegistrableDomain&& openerDomain)
344 {
345     ASSERT(RunLoop::isMain());
346
347     // It is safe to move the strings to the background queue without isolated copy here because they are r-value references
348     // coming from IPC. Strings which are safe to move to other threads as long as nobody on this thread holds a reference
349     // to those strings.
350     postTask([this, domainInNeedOfStorageAccess = WTFMove(domainInNeedOfStorageAccess), openerPageID, openerDomain = WTFMove(openerDomain)]() mutable {
351         if (m_memoryStore)
352             m_memoryStore->requestStorageAccessUnderOpener(WTFMove(domainInNeedOfStorageAccess), openerPageID, WTFMove(openerDomain));
353     });
354 }
355
356 void WebResourceLoadStatisticsStore::grantStorageAccess(const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, uint64_t frameID, uint64_t pageID, bool userWasPromptedNow, CompletionHandler<void(bool)>&& completionHandler)
357 {
358     ASSERT(RunLoop::isMain());
359     postTask([this, subFrameDomain = subFrameDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), frameID, pageID, userWasPromptedNow, completionHandler = WTFMove(completionHandler)]() mutable {
360         if (!m_memoryStore) {
361             postTaskReply([completionHandler = WTFMove(completionHandler)]() mutable {
362                 completionHandler(false);
363             });
364             return;
365         }
366
367         m_memoryStore->grantStorageAccess(WTFMove(subFrameDomain), WTFMove(topFrameDomain), frameID, pageID, userWasPromptedNow, [completionHandler = WTFMove(completionHandler)](bool wasGrantedAccess) mutable {
368             postTaskReply([completionHandler = WTFMove(completionHandler), wasGrantedAccess]() mutable {
369                 completionHandler(wasGrantedAccess);
370             });
371         });
372     });
373 }
374
375 bool WebResourceLoadStatisticsStore::grantStorageAccess(const RegistrableDomain& resourceDomain, const RegistrableDomain& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID)
376 {
377     bool isStorageGranted = false;
378
379     if (m_networkSession) {
380         m_networkSession->networkStorageSession().grantStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID);
381         ASSERT(m_networkSession->networkStorageSession().hasStorageAccess(resourceDomain, firstPartyDomain, frameID, pageID));
382         isStorageGranted = true;
383     }
384
385     return isStorageGranted;
386 }
387
388 void WebResourceLoadStatisticsStore::callGrantStorageAccessHandler(const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, Optional<uint64_t> frameID, uint64_t pageID, CompletionHandler<void(bool)>&& callback)
389 {
390     ASSERT(RunLoop::isMain());
391
392     callback(grantStorageAccess(subFrameDomain, topFrameDomain, frameID, pageID));
393 }
394
395 void WebResourceLoadStatisticsStore::didCreateNetworkProcess()
396 {
397     ASSERT(RunLoop::isMain());
398
399     postTask([this] {
400         if (!m_memoryStore)
401             return;
402         m_memoryStore->didCreateNetworkProcess();
403     });
404 }
405
406 void WebResourceLoadStatisticsStore::removeAllStorageAccess(CompletionHandler<void()>&& completionHandler)
407 {
408     ASSERT(RunLoop::isMain());
409
410     if (m_networkSession)
411         m_networkSession->networkStorageSession().removeAllStorageAccess();
412
413     completionHandler();
414 }
415
416 void WebResourceLoadStatisticsStore::applicationWillTerminate()
417 {
418     flushAndDestroyPersistentStore();
419 }
420
421 void WebResourceLoadStatisticsStore::performDailyTasks()
422 {
423     ASSERT(RunLoop::isMain());
424
425     postTask([this] {
426         if (!m_memoryStore)
427             return;
428
429         m_memoryStore->includeTodayAsOperatingDateIfNecessary();
430         m_memoryStore->calculateAndSubmitTelemetry();
431     });
432 }
433
434 void WebResourceLoadStatisticsStore::submitTelemetry(CompletionHandler<void()>&& completionHandler)
435 {
436     ASSERT(RunLoop::isMain());
437
438     postTask([this, completionHandler = WTFMove(completionHandler)]() mutable  {
439         if (m_memoryStore)
440             WebResourceLoadStatisticsTelemetry::calculateAndSubmit(*m_memoryStore);
441
442         postTaskReply(WTFMove(completionHandler));
443     });
444 }
445
446 void WebResourceLoadStatisticsStore::logFrameNavigation(const WebFrameProxy& frame, const URL& pageURL, const WebCore::ResourceRequest& request, const URL& redirectURL)
447 {
448     ASSERT(RunLoop::isMain());
449
450     auto sourceURL = redirectURL;
451     bool isRedirect = !redirectURL.isNull();
452     if (!isRedirect) {
453         sourceURL = frame.url();
454         if (sourceURL.isNull())
455             sourceURL = pageURL;
456     }
457
458     auto& targetURL = request.url();
459
460     if (!targetURL.isValid() || !pageURL.isValid())
461         return;
462
463     auto targetHost = targetURL.host();
464     auto mainFrameHost = pageURL.host();
465
466     if (targetHost.isEmpty() || mainFrameHost.isEmpty() || targetHost == sourceURL.host())
467         return;
468
469     RegistrableDomain targetDomain { targetURL };
470     RegistrableDomain topFrameDomain { pageURL };
471     RegistrableDomain sourceDomain { sourceURL };
472
473     logFrameNavigation(targetDomain, topFrameDomain, sourceDomain, isRedirect, frame.isMainFrame());
474 }
475
476 void WebResourceLoadStatisticsStore::logFrameNavigation(const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, const RegistrableDomain& sourceDomain, bool isRedirect, bool isMainFrame)
477 {
478     postTask([this, targetDomain = targetDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), sourceDomain = sourceDomain.isolatedCopy(), isRedirect, isMainFrame] {
479
480         if (m_memoryStore)
481             m_memoryStore->logFrameNavigation(targetDomain, topFrameDomain, sourceDomain, isRedirect, isMainFrame);
482     });
483 }
484
485 void WebResourceLoadStatisticsStore::logWebSocketLoading(const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, WallTime lastSeen, CompletionHandler<void()>&& completionHandler)
486 {
487     postTask([this, targetDomain = targetDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), lastSeen, completionHandler = WTFMove(completionHandler)]() mutable {
488         if (m_memoryStore)
489             m_memoryStore->logSubresourceLoading(targetDomain, topFrameDomain, lastSeen);
490
491         postTaskReply(WTFMove(completionHandler));
492     });
493 }
494
495 void WebResourceLoadStatisticsStore::logSubresourceLoading(const RegistrableDomain& targetDomain, const RegistrableDomain& topFrameDomain, WallTime lastSeen, CompletionHandler<void()>&& completionHandler)
496 {
497     postTask([this, targetDomain = targetDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), lastSeen, completionHandler = WTFMove(completionHandler)]() mutable {
498         if (m_memoryStore)
499             m_memoryStore->logSubresourceLoading(targetDomain, topFrameDomain, lastSeen);
500
501         postTaskReply(WTFMove(completionHandler));
502     });
503 }
504
505 void WebResourceLoadStatisticsStore::logSubresourceRedirect(const RegistrableDomain& sourceDomain, const RegistrableDomain& targetDomain, CompletionHandler<void()>&& completionHandler)
506 {
507     postTask([this, sourceDomain = sourceDomain.isolatedCopy(), targetDomain = targetDomain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
508         if (m_memoryStore)
509             m_memoryStore->logSubresourceRedirect(sourceDomain, targetDomain);
510
511         postTaskReply(WTFMove(completionHandler));
512     });
513 }
514
515 void WebResourceLoadStatisticsStore::logUserInteraction(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
516 {
517     ASSERT(RunLoop::isMain());
518
519     postTask([this, domain = domain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
520         if (m_memoryStore)
521             m_memoryStore->logUserInteraction(domain);
522         postTaskReply(WTFMove(completionHandler));
523     });
524 }
525
526 void WebResourceLoadStatisticsStore::clearUserInteraction(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
527 {
528     ASSERT(RunLoop::isMain());
529     
530     postTask([this, domain = domain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
531         if (m_memoryStore)
532             m_memoryStore->clearUserInteraction(domain);
533         postTaskReply(WTFMove(completionHandler));
534     });
535 }
536
537 void WebResourceLoadStatisticsStore::hasHadUserInteraction(const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
538 {
539     postTask([this, domain, completionHandler = WTFMove(completionHandler)]() mutable {
540         bool hadUserInteraction = m_memoryStore ? m_memoryStore->hasHadUserInteraction(domain) : false;
541         postTaskReply([hadUserInteraction, completionHandler = WTFMove(completionHandler)]() mutable {
542             completionHandler(hadUserInteraction);
543         });
544     });
545 }
546
547 void WebResourceLoadStatisticsStore::setLastSeen(const RegistrableDomain& domain, Seconds seconds, CompletionHandler<void()>&& completionHandler)
548 {
549     ASSERT(RunLoop::isMain());
550     
551     postTask([this, domain = domain.isolatedCopy(), seconds, completionHandler = WTFMove(completionHandler)]() mutable {
552         if (m_memoryStore)
553             m_memoryStore->setLastSeen(domain, seconds);
554         postTaskReply(WTFMove(completionHandler));
555     });
556 }
557     
558 void WebResourceLoadStatisticsStore::setPrevalentResource(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
559 {
560     ASSERT(RunLoop::isMain());
561
562     postTask([this, domain = domain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
563         if (m_memoryStore)
564             m_memoryStore->setPrevalentResource(domain);
565         postTaskReply(WTFMove(completionHandler));
566     });
567 }
568
569 void WebResourceLoadStatisticsStore::setVeryPrevalentResource(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
570 {
571     ASSERT(RunLoop::isMain());
572
573     postTask([this, domain = domain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
574         if (m_memoryStore)
575             m_memoryStore->setVeryPrevalentResource(domain);
576         postTaskReply(WTFMove(completionHandler));
577     });
578 }
579     
580 void WebResourceLoadStatisticsStore::dumpResourceLoadStatistics(CompletionHandler<void(String)>&& completionHandler)
581 {
582     ASSERT(RunLoop::isMain());
583
584     postTask([this, completionHandler = WTFMove(completionHandler)]() mutable {
585         String result = m_memoryStore ? m_memoryStore->dumpResourceLoadStatistics() : emptyString();
586         postTaskReply([result = result.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
587             completionHandler(result);
588         });
589     });
590 }
591
592 void WebResourceLoadStatisticsStore::isPrevalentResource(const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
593 {
594     ASSERT(RunLoop::isMain());
595     
596     postTask([this, domain = domain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
597         bool isPrevalentResource = m_memoryStore ? m_memoryStore->isPrevalentResource(domain) : false;
598         postTaskReply([isPrevalentResource, completionHandler = WTFMove(completionHandler)]() mutable {
599             completionHandler(isPrevalentResource);
600         });
601     });
602 }
603     
604 void WebResourceLoadStatisticsStore::isVeryPrevalentResource(const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
605 {
606     ASSERT(RunLoop::isMain());
607     
608     postTask([this, domain = domain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
609         bool isVeryPrevalentResource = m_memoryStore ? m_memoryStore->isVeryPrevalentResource(domain) : false;
610         postTaskReply([isVeryPrevalentResource, completionHandler = WTFMove(completionHandler)]() mutable {
611             completionHandler(isVeryPrevalentResource);
612         });
613     });
614 }
615
616 void WebResourceLoadStatisticsStore::isRegisteredAsSubresourceUnder(const RegistrableDomain& subresourceDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void(bool)>&& completionHandler)
617 {
618     ASSERT(RunLoop::isMain());
619
620     postTask([this, subresourceDomain = subresourceDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
621         bool isRegisteredAsSubresourceUnder = m_memoryStore ? m_memoryStore->isRegisteredAsSubresourceUnder(subresourceDomain, topFrameDomain) : false;
622         postTaskReply([isRegisteredAsSubresourceUnder, completionHandler = WTFMove(completionHandler)]() mutable {
623             completionHandler(isRegisteredAsSubresourceUnder);
624         });
625     });
626 }
627
628 void WebResourceLoadStatisticsStore::isRegisteredAsSubFrameUnder(const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void(bool)>&& completionHandler)
629 {
630     ASSERT(RunLoop::isMain());
631
632     postTask([this, subFrameDomain = subFrameDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
633         bool isRegisteredAsSubFrameUnder = m_memoryStore ? m_memoryStore->isRegisteredAsSubFrameUnder(subFrameDomain, topFrameDomain) : false;
634         postTaskReply([isRegisteredAsSubFrameUnder, completionHandler = WTFMove(completionHandler)]() mutable {
635             completionHandler(isRegisteredAsSubFrameUnder);
636         });
637     });
638 }
639
640 void WebResourceLoadStatisticsStore::isRegisteredAsRedirectingTo(const RegistrableDomain& domainRedirectedFrom, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void(bool)>&& completionHandler)
641 {
642     ASSERT(RunLoop::isMain());
643
644     postTask([this, domainRedirectedFrom = domainRedirectedFrom.isolatedCopy(), domainRedirectedTo = domainRedirectedTo.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
645         bool isRegisteredAsRedirectingTo = m_memoryStore ? m_memoryStore->isRegisteredAsRedirectingTo(domainRedirectedFrom, domainRedirectedTo) : false;
646         postTaskReply([isRegisteredAsRedirectingTo, completionHandler = WTFMove(completionHandler)]() mutable {
647             completionHandler(isRegisteredAsRedirectingTo);
648         });
649     });
650 }
651
652 void WebResourceLoadStatisticsStore::clearPrevalentResource(const RegistrableDomain& domain, CompletionHandler<void()>&& completionHandler)
653 {
654     ASSERT(RunLoop::isMain());
655     
656     postTask([this, domain = domain.isolatedCopy(), completionHandler = WTFMove(completionHandler)]() mutable {
657         if (m_memoryStore)
658             m_memoryStore->clearPrevalentResource(domain);
659         postTaskReply(WTFMove(completionHandler));
660     });
661 }
662
663 void WebResourceLoadStatisticsStore::setGrandfathered(const RegistrableDomain& domain, bool value, CompletionHandler<void()>&& completionHandler)
664 {
665     ASSERT(RunLoop::isMain());
666
667     postTask([this, domain = domain.isolatedCopy(), value, completionHandler = WTFMove(completionHandler)]() mutable {
668         if (m_memoryStore)
669             m_memoryStore->setGrandfathered(domain, value);
670         postTaskReply(WTFMove(completionHandler));
671     });
672 }
673     
674 void WebResourceLoadStatisticsStore::isGrandfathered(const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
675 {
676     ASSERT(RunLoop::isMain());
677
678     postTask([this, completionHandler = WTFMove(completionHandler), domain = domain.isolatedCopy()]() mutable {
679         bool isGrandFathered = m_memoryStore ? m_memoryStore->isGrandfathered(domain) : false;
680         postTaskReply([isGrandFathered, completionHandler = WTFMove(completionHandler)]() mutable {
681             completionHandler(isGrandFathered);
682         });
683     });
684 }
685
686 void WebResourceLoadStatisticsStore::setSubframeUnderTopFrameDomain(const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void()>&& completionHandler)
687 {
688     ASSERT(RunLoop::isMain());
689     
690     postTask([this, completionHandler = WTFMove(completionHandler), subFrameDomain = subFrameDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy()]() mutable {
691         if (m_memoryStore)
692             m_memoryStore->setSubframeUnderTopFrameDomain(subFrameDomain, topFrameDomain);
693         postTaskReply(WTFMove(completionHandler));
694     });
695 }
696
697 void WebResourceLoadStatisticsStore::setSubresourceUnderTopFrameDomain(const RegistrableDomain& subresourceDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void()>&& completionHandler)
698 {
699     ASSERT(RunLoop::isMain());
700     
701     postTask([this, completionHandler = WTFMove(completionHandler), subresourceDomain = subresourceDomain.isolatedCopy(), topFrameDomain = topFrameDomain.isolatedCopy()]() mutable {
702         if (m_memoryStore)
703             m_memoryStore->setSubresourceUnderTopFrameDomain(subresourceDomain, topFrameDomain);
704         postTaskReply(WTFMove(completionHandler));
705     });
706 }
707
708 void WebResourceLoadStatisticsStore::setSubresourceUniqueRedirectTo(const RegistrableDomain& subresourceDomain, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void()>&& completionHandler)
709 {
710     ASSERT(RunLoop::isMain());
711     
712     postTask([this, completionHandler = WTFMove(completionHandler), subresourceDomain = subresourceDomain.isolatedCopy(), domainRedirectedTo = domainRedirectedTo.isolatedCopy()]() mutable {
713         if (m_memoryStore)
714             m_memoryStore->setSubresourceUniqueRedirectTo(subresourceDomain, domainRedirectedTo);
715         postTaskReply(WTFMove(completionHandler));
716     });
717 }
718
719 void WebResourceLoadStatisticsStore::setSubresourceUniqueRedirectFrom(const RegistrableDomain& subresourceDomain, const RegistrableDomain& domainRedirectedFrom, CompletionHandler<void()>&& completionHandler)
720 {
721     ASSERT(RunLoop::isMain());
722     
723     postTask([this, completionHandler = WTFMove(completionHandler), subresourceDomain = subresourceDomain.isolatedCopy(), domainRedirectedFrom = domainRedirectedFrom.isolatedCopy()]() mutable {
724         if (m_memoryStore)
725             m_memoryStore->setSubresourceUniqueRedirectFrom(subresourceDomain, domainRedirectedFrom);
726         postTaskReply(WTFMove(completionHandler));
727     });
728 }
729
730 void WebResourceLoadStatisticsStore::setTopFrameUniqueRedirectTo(const RegistrableDomain& topFrameDomain, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void()>&& completionHandler)
731 {
732     ASSERT(RunLoop::isMain());
733     
734     postTask([this, completionHandler = WTFMove(completionHandler), topFrameDomain = topFrameDomain.isolatedCopy(), domainRedirectedTo = domainRedirectedTo.isolatedCopy()]() mutable {
735         if (m_memoryStore)
736             m_memoryStore->setTopFrameUniqueRedirectTo(topFrameDomain, domainRedirectedTo);
737         postTaskReply(WTFMove(completionHandler));
738     });
739 }
740
741 void WebResourceLoadStatisticsStore::setTopFrameUniqueRedirectFrom(const RegistrableDomain& topFrameDomain, const RegistrableDomain& domainRedirectedFrom, CompletionHandler<void()>&& completionHandler)
742 {
743     ASSERT(RunLoop::isMain());
744     
745     postTask([this, completionHandler = WTFMove(completionHandler), topFrameDomain = topFrameDomain.isolatedCopy(), domainRedirectedFrom = domainRedirectedFrom.isolatedCopy()]() mutable {
746         if (m_memoryStore)
747             m_memoryStore->setTopFrameUniqueRedirectFrom(topFrameDomain, domainRedirectedFrom);
748         postTaskReply(WTFMove(completionHandler));
749     });
750 }
751
752 void WebResourceLoadStatisticsStore::scheduleCookieBlockingUpdate(CompletionHandler<void()>&& completionHandler)
753 {
754     // Helper function used by testing system. Should only be called from the main thread.
755     ASSERT(RunLoop::isMain());
756
757     postTask([this, completionHandler = WTFMove(completionHandler)]() mutable {
758         if (!m_memoryStore) {
759             postTaskReply(WTFMove(completionHandler));
760             return;
761         }
762         m_memoryStore->updateCookieBlocking([completionHandler = WTFMove(completionHandler)]() mutable {
763             postTaskReply(WTFMove(completionHandler));
764         });
765     });
766 }
767
768 void WebResourceLoadStatisticsStore::scheduleCookieBlockingUpdateForDomains(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
769 {
770     // Helper function used by testing system. Should only be called from the main thread.
771     ASSERT(RunLoop::isMain());
772     postTask([this, domainsToBlock = crossThreadCopy(domainsToBlock), completionHandler = WTFMove(completionHandler)]() mutable {
773         if (!m_memoryStore) {
774             postTaskReply(WTFMove(completionHandler));
775             return;
776         }
777
778         m_memoryStore->updateCookieBlockingForDomains(domainsToBlock, [completionHandler = WTFMove(completionHandler)]() mutable {
779             postTaskReply(WTFMove(completionHandler));
780         });
781     });
782 }
783
784 void WebResourceLoadStatisticsStore::scheduleClearBlockingStateForDomains(const Vector<RegistrableDomain>& domains, CompletionHandler<void()>&& completionHandler)
785 {
786     // Helper function used by testing system. Should only be called from the main thread.
787     ASSERT(RunLoop::isMain());
788     postTask([this, domains = crossThreadCopy(domains), completionHandler = WTFMove(completionHandler)]() mutable {
789         if (!m_memoryStore) {
790             postTaskReply(WTFMove(completionHandler));
791             return;
792         }
793
794         m_memoryStore->clearBlockingStateForDomains(domains, [completionHandler = WTFMove(completionHandler)]() mutable {
795             postTaskReply(WTFMove(completionHandler));
796         });
797     });
798 }
799
800 void WebResourceLoadStatisticsStore::scheduleClearInMemoryAndPersistent(ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
801 {
802     ASSERT(RunLoop::isMain());
803     postTask([this, protectedThis = makeRef(*this), shouldGrandfather, completionHandler = WTFMove(completionHandler)]() mutable {
804         if (m_persistentStorage)
805             m_persistentStorage->clear();
806
807         CompletionHandlerCallingScope completionHandlerCaller([completionHandler = WTFMove(completionHandler)]() mutable {
808             postTaskReply(WTFMove(completionHandler));
809         });
810
811         if (m_memoryStore) {
812             m_memoryStore->clear([this, protectedThis = protectedThis.copyRef(), shouldGrandfather, completionHandlerCaller = WTFMove(completionHandlerCaller)] () mutable {
813                 if (shouldGrandfather == ShouldGrandfatherStatistics::Yes) {
814                     if (m_memoryStore)
815                         m_memoryStore->grandfatherExistingWebsiteData(completionHandlerCaller.release());
816                     else
817                         RELEASE_LOG(ResourceLoadStatistics, "WebResourceLoadStatisticsStore::scheduleClearInMemoryAndPersistent After being cleared, m_memoryStore is null when trying to grandfather data.");
818                 }
819             });
820         } else {
821             if (shouldGrandfather == ShouldGrandfatherStatistics::Yes)
822                 RELEASE_LOG(ResourceLoadStatistics, "WebResourceLoadStatisticsStore::scheduleClearInMemoryAndPersistent Before being cleared, m_memoryStore is null when trying to grandfather data.");
823         }
824     });
825 }
826
827 void WebResourceLoadStatisticsStore::scheduleClearInMemoryAndPersistent(WallTime modifiedSince, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& callback)
828 {
829     ASSERT(RunLoop::isMain());
830
831     // For now, be conservative and clear everything regardless of modifiedSince.
832     UNUSED_PARAM(modifiedSince);
833     scheduleClearInMemoryAndPersistent(shouldGrandfather, WTFMove(callback));
834 }
835
836 void WebResourceLoadStatisticsStore::setTimeToLiveUserInteraction(Seconds seconds, CompletionHandler<void()>&& completionHandler)
837 {
838     ASSERT(RunLoop::isMain());
839     postTask([this, seconds, completionHandler = WTFMove(completionHandler)]() mutable {
840         if (m_memoryStore)
841             m_memoryStore->setTimeToLiveUserInteraction(seconds);
842         postTaskReply(WTFMove(completionHandler));
843     });
844 }
845
846 void WebResourceLoadStatisticsStore::setMinimumTimeBetweenDataRecordsRemoval(Seconds seconds, CompletionHandler<void()>&& completionHandler)
847 {
848     ASSERT(RunLoop::isMain());
849     postTask([this, seconds, completionHandler = WTFMove(completionHandler)]() mutable  {
850         if (m_memoryStore)
851             m_memoryStore->setMinimumTimeBetweenDataRecordsRemoval(seconds);
852
853         postTaskReply(WTFMove(completionHandler));
854     });
855 }
856
857 void WebResourceLoadStatisticsStore::setGrandfatheringTime(Seconds seconds, CompletionHandler<void()>&& completionHandler)
858 {
859     ASSERT(RunLoop::isMain());
860     postTask([this, seconds, completionHandler = WTFMove(completionHandler)]() mutable  {
861         if (m_memoryStore)
862             m_memoryStore->setGrandfatheringTime(seconds);
863
864         postTaskReply(WTFMove(completionHandler));
865     });
866 }
867
868 void WebResourceLoadStatisticsStore::setCacheMaxAgeCap(Seconds seconds, CompletionHandler<void()>&& completionHandler)
869 {
870     ASSERT(RunLoop::isMain());
871     ASSERT(seconds >= 0_s);
872     
873     if (m_networkSession)
874         m_networkSession->networkStorageSession().setCacheMaxAgeCapForPrevalentResources(seconds);
875
876     completionHandler();
877 }
878
879 void WebResourceLoadStatisticsStore::callUpdatePrevalentDomainsToBlockCookiesForHandler(const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
880 {
881     ASSERT(RunLoop::isMain());
882
883     if (m_networkSession)
884         m_networkSession->networkStorageSession().setPrevalentDomainsToBlockCookiesFor(domainsToBlock);
885
886     completionHandler();
887 }
888
889 void WebResourceLoadStatisticsStore::removePrevalentDomains(const Vector<RegistrableDomain>& domains)
890 {
891     if (m_networkSession)
892         m_networkSession->networkStorageSession().removePrevalentDomains(domains);
893 }
894
895 void WebResourceLoadStatisticsStore::callRemoveDomainsHandler(const Vector<RegistrableDomain>& domains)
896 {
897     ASSERT(RunLoop::isMain());
898
899     removePrevalentDomains(domains);
900 }
901     
902 void WebResourceLoadStatisticsStore::setMaxStatisticsEntries(size_t maximumEntryCount, CompletionHandler<void()>&& completionHandler)
903 {
904     ASSERT(RunLoop::isMain());
905     postTask([this, maximumEntryCount, completionHandler = WTFMove(completionHandler)]() mutable  {
906         if (m_memoryStore)
907             m_memoryStore->setMaxStatisticsEntries(maximumEntryCount);
908
909         postTaskReply(WTFMove(completionHandler));
910     });
911 }
912     
913 void WebResourceLoadStatisticsStore::setPruneEntriesDownTo(size_t pruneTargetCount, CompletionHandler<void()>&& completionHandler)
914 {
915     ASSERT(RunLoop::isMain());
916
917     postTask([this, pruneTargetCount, completionHandler = WTFMove(completionHandler)]() mutable  {
918         if (m_memoryStore)
919             m_memoryStore->setPruneEntriesDownTo(pruneTargetCount);
920
921         postTaskReply(WTFMove(completionHandler));
922     });
923 }
924
925 void WebResourceLoadStatisticsStore::resetParametersToDefaultValues(CompletionHandler<void()>&& completionHandler)
926 {
927     ASSERT(RunLoop::isMain());
928
929     postTask([this, completionHandler = WTFMove(completionHandler)]() mutable {
930         if (m_memoryStore)
931             m_memoryStore->resetParametersToDefaultValues();
932
933         postTaskReply(WTFMove(completionHandler));
934     });
935 }
936
937 void WebResourceLoadStatisticsStore::logTestingEvent(const String& event)
938 {
939     ASSERT(RunLoop::isMain());
940
941     if (m_networkSession)
942         m_networkSession->networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::LogTestingEvent(m_networkSession->sessionID(), event), 0);
943 }
944
945 void WebResourceLoadStatisticsStore::notifyResourceLoadStatisticsProcessed()
946 {
947     ASSERT(RunLoop::isMain());
948     
949     if (m_networkSession)
950         m_networkSession->notifyResourceLoadStatisticsProcessed();
951 }
952
953 void WebResourceLoadStatisticsStore::deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(OptionSet<WebsiteDataType> dataTypes, Vector<RegistrableDomain>&& domains, bool shouldNotifyPage, CompletionHandler<void(const HashSet<RegistrableDomain>&)>&& completionHandler)
954 {
955     ASSERT(RunLoop::isMain());
956     
957     if (m_networkSession) {
958         m_networkSession->deleteWebsiteDataForRegistrableDomainsInAllPersistentDataStores(dataTypes, WTFMove(domains), shouldNotifyPage, WTFMove(completionHandler));
959         return;
960     }
961
962     completionHandler({ });
963 }
964
965 void WebResourceLoadStatisticsStore::registrableDomainsWithWebsiteData(OptionSet<WebsiteDataType> dataTypes, bool shouldNotifyPage, CompletionHandler<void(HashSet<RegistrableDomain>&&)>&& completionHandler)
966 {
967     ASSERT(RunLoop::isMain());
968     
969     if (m_networkSession) {
970         m_networkSession->registrableDomainsWithWebsiteData(dataTypes, shouldNotifyPage, WTFMove(completionHandler));
971         return;
972     }
973
974     completionHandler({ });
975 }
976
977 void WebResourceLoadStatisticsStore::sendDiagnosticMessageWithValue(const String& message, const String& description, unsigned value, unsigned sigDigits, WebCore::ShouldSample shouldSample) const
978 {
979     if (m_networkSession)
980         const_cast<WebResourceLoadStatisticsStore*>(this)->networkSession()->logDiagnosticMessageWithValue(message, description, value, sigDigits, shouldSample);
981 }
982
983 void WebResourceLoadStatisticsStore::notifyPageStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins) const
984 {
985     if (m_networkSession)
986         const_cast<WebResourceLoadStatisticsStore*>(this)->networkSession()->notifyPageStatisticsTelemetryFinished(totalPrevalentResources, totalPrevalentResourcesWithUserInteraction, top3SubframeUnderTopFrameOrigins);
987 }
988
989 } // namespace WebKit
990
991 #endif