RenderStyle::resetPadding sets incorrect computed value (auto)
[WebKit-https.git] / Source / WebKit / UIProcess / WebsiteData / WebsiteDataStore.cpp
1 /*
2  * Copyright (C) 2014-2020 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 "WebsiteDataStore.h"
28
29 #include "APIHTTPCookieStore.h"
30 #include "APIProcessPoolConfiguration.h"
31 #include "APIWebsiteDataRecord.h"
32 #include "AuthenticatorManager.h"
33 #include "DeviceIdHashSaltStorage.h"
34 #include "GPUProcessProxy.h"
35 #include "MockAuthenticatorManager.h"
36 #include "NetworkProcessMessages.h"
37 #include "ShouldGrandfatherStatistics.h"
38 #include "StorageAccessStatus.h"
39 #include "WebBackForwardCache.h"
40 #include "WebKit2Initialize.h"
41 #include "WebPageProxy.h"
42 #include "WebProcessCache.h"
43 #include "WebProcessMessages.h"
44 #include "WebProcessPool.h"
45 #include "WebResourceLoadStatisticsStore.h"
46 #include "WebsiteData.h"
47 #include "WebsiteDataStoreClient.h"
48 #include "WebsiteDataStoreParameters.h"
49 #include <WebCore/ApplicationCacheStorage.h>
50 #include <WebCore/CredentialStorage.h>
51 #include <WebCore/DatabaseTracker.h>
52 #include <WebCore/HTMLMediaElement.h>
53 #include <WebCore/NetworkStorageSession.h>
54 #include <WebCore/OriginLock.h>
55 #include <WebCore/RegistrableDomain.h>
56 #include <WebCore/SecurityOrigin.h>
57 #include <WebCore/SecurityOriginData.h>
58 #include <WebCore/StorageQuotaManager.h>
59 #include <wtf/CallbackAggregator.h>
60 #include <wtf/CompletionHandler.h>
61 #include <wtf/CrossThreadCopier.h>
62 #include <wtf/FileSystem.h>
63 #include <wtf/ProcessPrivilege.h>
64 #include <wtf/RunLoop.h>
65
66 #if ENABLE(NETSCAPE_PLUGIN_API)
67 #include "PluginProcessManager.h"
68 #endif
69
70 #if HAVE(SEC_KEY_PROXY)
71 #include "SecKeyProxyStore.h"
72 #endif
73
74 #if HAVE(APP_SSO)
75 #include "SOAuthorizationCoordinator.h"
76 #endif
77
78 namespace WebKit {
79
80 static bool allowsWebsiteDataRecordsForAllOrigins;
81 void WebsiteDataStore::allowWebsiteDataRecordsForAllOrigins()
82 {
83     allowsWebsiteDataRecordsForAllOrigins = true;
84 }
85
86 static HashMap<PAL::SessionID, WebsiteDataStore*>& nonDefaultDataStores()
87 {
88     RELEASE_ASSERT(isUIThread());
89     static NeverDestroyed<HashMap<PAL::SessionID, WebsiteDataStore*>> map;
90     return map;
91 }
92
93 Ref<WebsiteDataStore> WebsiteDataStore::createNonPersistent()
94 {
95     return adoptRef(*new WebsiteDataStore(WebsiteDataStoreConfiguration::create(IsPersistent::No), PAL::SessionID::generateEphemeralSessionID()));
96 }
97
98 Ref<WebsiteDataStore> WebsiteDataStore::create(Ref<WebsiteDataStoreConfiguration>&& configuration, PAL::SessionID sessionID)
99 {
100     return adoptRef(*new WebsiteDataStore(WTFMove(configuration), sessionID));
101 }
102
103 WebsiteDataStore::WebsiteDataStore(Ref<WebsiteDataStoreConfiguration>&& configuration, PAL::SessionID sessionID)
104     : m_sessionID(sessionID)
105     , m_resolvedConfiguration(WTFMove(configuration))
106     , m_configuration(m_resolvedConfiguration->copy())
107     , m_deviceIdHashSaltStorage(DeviceIdHashSaltStorage::create(isPersistent() ? m_configuration->deviceIdHashSaltsStorageDirectory() : String()))
108     , m_queue(WorkQueue::create("com.apple.WebKit.WebsiteDataStore"))
109 #if ENABLE(WEB_AUTHN)
110     , m_authenticatorManager(makeUniqueRef<AuthenticatorManager>())
111 #endif
112     , m_client(makeUniqueRef<WebsiteDataStoreClient>())
113 #if HAVE(APP_SSO)
114     , m_soAuthorizationCoordinator(makeUniqueRef<SOAuthorizationCoordinator>())
115 #endif
116 {
117     WTF::setProcessPrivileges(allPrivileges());
118     maybeRegisterWithSessionIDMap();
119     platformInitialize();
120
121     ASSERT(RunLoop::isMain());
122 }
123
124 WebsiteDataStore::~WebsiteDataStore()
125 {
126     ASSERT(RunLoop::isMain());
127     RELEASE_ASSERT(m_sessionID.isValid());
128
129     platformDestroy();
130
131     if (m_sessionID != PAL::SessionID::defaultSessionID()) {
132         ASSERT(nonDefaultDataStores().get(m_sessionID) == this);
133         nonDefaultDataStores().remove(m_sessionID);
134         for (auto& processPool : WebProcessPool::allProcessPools()) {
135             if (auto* networkProcess = processPool->networkProcess())
136                 networkProcess->removeSession(m_sessionID);
137         }
138     }
139 #if ENABLE(GPU_PROCESS)
140         if (auto* gpuProcessProxy = GPUProcessProxy::singletonIfCreated())
141             gpuProcessProxy->removeSession(m_sessionID);
142 #endif
143 }
144
145 static RefPtr<WebsiteDataStore>& globalDefaultDataStore()
146 {
147     static NeverDestroyed<RefPtr<WebsiteDataStore>> globalDefaultDataStore;
148     return globalDefaultDataStore.get();
149 }
150
151 Ref<WebsiteDataStore> WebsiteDataStore::defaultDataStore()
152 {
153     InitializeWebKit2();
154
155     auto& store = globalDefaultDataStore();
156     if (!store)
157         store = adoptRef(new WebsiteDataStore(WebsiteDataStoreConfiguration::create(IsPersistent::Yes), PAL::SessionID::defaultSessionID()));
158
159     return *store;
160 }
161
162 void WebsiteDataStore::deleteDefaultDataStoreForTesting()
163 {
164     globalDefaultDataStore() = nullptr;
165 }
166
167 bool WebsiteDataStore::defaultDataStoreExists()
168 {
169     return !!globalDefaultDataStore();
170 }
171
172 void WebsiteDataStore::maybeRegisterWithSessionIDMap()
173 {
174     if (m_sessionID != PAL::SessionID::defaultSessionID()) {
175         auto result = nonDefaultDataStores().add(m_sessionID, this);
176         ASSERT_UNUSED(result, result.isNewEntry);
177     }
178 }
179
180 WebsiteDataStore* WebsiteDataStore::existingNonDefaultDataStoreForSessionID(PAL::SessionID sessionID)
181 {
182     return sessionID != PAL::SessionID::defaultSessionID() ? nonDefaultDataStores().get(sessionID) : nullptr;
183 }
184
185 void WebsiteDataStore::registerProcess(WebProcessProxy& process)
186 {
187     ASSERT(process.pageCount() || process.provisionalPageCount());
188     m_processes.add(process);
189 }
190
191 void WebsiteDataStore::unregisterProcess(WebProcessProxy& process)
192 {
193     ASSERT(!process.pageCount());
194     ASSERT(!process.provisionalPageCount());
195     m_processes.remove(process);
196 }
197
198 WebProcessPool* WebsiteDataStore::processPoolForCookieStorageOperations()
199 {
200     auto pools = processPools(1);
201     return pools.isEmpty() ? nullptr : pools.begin()->get();
202 }
203
204 void WebsiteDataStore::resolveDirectoriesIfNecessary()
205 {
206     if (m_hasResolvedDirectories)
207         return;
208     m_hasResolvedDirectories = true;
209
210     // Resolve directory paths.
211     if (!m_configuration->applicationCacheDirectory().isEmpty())
212         m_resolvedConfiguration->setApplicationCacheDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->applicationCacheDirectory()));
213     if (!m_configuration->mediaCacheDirectory().isEmpty())
214         m_resolvedConfiguration->setMediaCacheDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaCacheDirectory()));
215     if (!m_configuration->mediaKeysStorageDirectory().isEmpty())
216         m_resolvedConfiguration->setMediaKeysStorageDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaKeysStorageDirectory()));
217     if (!m_configuration->webSQLDatabaseDirectory().isEmpty())
218         m_resolvedConfiguration->setWebSQLDatabaseDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->webSQLDatabaseDirectory()));
219     if (!m_configuration->indexedDBDatabaseDirectory().isEmpty())
220         m_resolvedConfiguration->setIndexedDBDatabaseDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->indexedDBDatabaseDirectory()));
221     if (!m_configuration->alternativeServicesDirectory().isEmpty() && WebsiteDataStore::http3Enabled())
222         m_resolvedConfiguration->setAlternativeServicesDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->alternativeServicesDirectory()));
223     if (!m_configuration->deviceIdHashSaltsStorageDirectory().isEmpty())
224         m_resolvedConfiguration->setDeviceIdHashSaltsStorageDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->deviceIdHashSaltsStorageDirectory()));
225     if (!m_configuration->networkCacheDirectory().isEmpty())
226         m_resolvedConfiguration->setNetworkCacheDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->networkCacheDirectory()));
227     if (!m_configuration->resourceLoadStatisticsDirectory().isEmpty())
228         m_resolvedConfiguration->setResourceLoadStatisticsDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->resourceLoadStatisticsDirectory()));
229     if (!m_configuration->serviceWorkerRegistrationDirectory().isEmpty() && m_resolvedConfiguration->serviceWorkerRegistrationDirectory().isEmpty())
230         m_resolvedConfiguration->setServiceWorkerRegistrationDirectory(resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->serviceWorkerRegistrationDirectory()));
231     if (!m_configuration->javaScriptConfigurationDirectory().isEmpty())
232         m_resolvedConfiguration->setJavaScriptConfigurationDirectory(resolvePathForSandboxExtension(m_configuration->javaScriptConfigurationDirectory()));
233     if (!m_configuration->cacheStorageDirectory().isEmpty() && m_resolvedConfiguration->cacheStorageDirectory().isEmpty())
234         m_resolvedConfiguration->setCacheStorageDirectory(resolvePathForSandboxExtension(m_configuration->cacheStorageDirectory()));
235     if (!m_configuration->hstsStorageDirectory().isEmpty() && m_resolvedConfiguration->hstsStorageDirectory().isEmpty())
236         m_resolvedConfiguration->setHSTSStorageDirectory(resolvePathForSandboxExtension(m_configuration->hstsStorageDirectory()));
237
238     // Resolve directories for file paths.
239     if (!m_configuration->cookieStorageFile().isEmpty()) {
240         m_resolvedConfiguration->setCookieStorageFile(resolveAndCreateReadWriteDirectoryForSandboxExtension(FileSystem::directoryName(m_configuration->cookieStorageFile())));
241         m_resolvedConfiguration->setCookieStorageFile(FileSystem::pathByAppendingComponent(m_resolvedConfiguration->cookieStorageFile(), FileSystem::pathGetFileName(m_configuration->cookieStorageFile())));
242     }
243 }
244
245 enum class ProcessAccessType {
246     None,
247     OnlyIfLaunched,
248     Launch,
249 };
250
251 static ProcessAccessType computeNetworkProcessAccessTypeForDataFetch(OptionSet<WebsiteDataType> dataTypes, bool isNonPersistentStore)
252 {
253     for (auto dataType : dataTypes) {
254         if (WebsiteData::ownerProcess(dataType) == WebsiteDataProcessType::Network) {
255             if (isNonPersistentStore)
256                 return ProcessAccessType::OnlyIfLaunched;
257             return ProcessAccessType::Launch;
258         }
259     }
260     return ProcessAccessType::None;
261 }
262
263 static ProcessAccessType computeWebProcessAccessTypeForDataFetch(OptionSet<WebsiteDataType> dataTypes, bool isNonPersistentStore)
264 {
265     UNUSED_PARAM(isNonPersistentStore);
266
267     ProcessAccessType processAccessType = ProcessAccessType::None;
268
269     if (dataTypes.contains(WebsiteDataType::MemoryCache))
270         return ProcessAccessType::OnlyIfLaunched;
271
272     return processAccessType;
273 }
274
275 void WebsiteDataStore::fetchData(OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, Function<void(Vector<WebsiteDataRecord>)>&& completionHandler)
276 {
277     fetchDataAndApply(dataTypes, fetchOptions, nullptr, WTFMove(completionHandler));
278 }
279
280 void WebsiteDataStore::fetchDataAndApply(OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, RefPtr<WorkQueue>&& queue, Function<void(Vector<WebsiteDataRecord>)>&& apply)
281 {
282     struct CallbackAggregator final : ThreadSafeRefCounted<CallbackAggregator> {
283         CallbackAggregator(OptionSet<WebsiteDataFetchOption> fetchOptions, RefPtr<WorkQueue>&& queue, Function<void(Vector<WebsiteDataRecord>)>&& apply, WebsiteDataStore& dataStore)
284             : fetchOptions(fetchOptions)
285             , queue(WTFMove(queue))
286             , apply(WTFMove(apply))
287             , protectedDataStore(dataStore)
288         {
289             ASSERT(RunLoop::isMain());
290         }
291
292         ~CallbackAggregator()
293         {
294             ASSERT(!pendingCallbacks);
295
296             // Make sure the data store gets destroyed on the main thread even though the CallbackAggregator can get destroyed on a background queue.
297             RunLoop::main().dispatch([protectedDataStore = WTFMove(protectedDataStore)] { });
298         }
299
300         void addPendingCallback()
301         {
302             pendingCallbacks++;
303         }
304
305         void removePendingCallback(WebsiteData websiteData)
306         {
307             ASSERT(pendingCallbacks);
308             --pendingCallbacks;
309
310             for (auto& entry : websiteData.entries) {
311                 auto displayName = WebsiteDataRecord::displayNameForOrigin(entry.origin);
312                 if (!displayName) {
313                     if (!allowsWebsiteDataRecordsForAllOrigins)
314                         continue;
315
316                     String hostString = entry.origin.host.isEmpty() ? "" : makeString(" ", entry.origin.host);
317                     displayName = makeString(entry.origin.protocol, hostString);
318                 }
319
320                 auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value;
321                 if (!record.displayName)
322                     record.displayName = WTFMove(displayName);
323
324                 record.add(entry.type, entry.origin);
325
326                 if (fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes)) {
327                     if (!record.size)
328                         record.size = WebsiteDataRecord::Size { 0, { } };
329
330                     record.size->totalSize += entry.size;
331                     record.size->typeSizes.add(static_cast<unsigned>(entry.type), 0).iterator->value += entry.size;
332                 }
333             }
334
335             for (auto& hostName : websiteData.hostNamesWithCookies) {
336                 auto displayName = WebsiteDataRecord::displayNameForCookieHostName(hostName);
337                 if (!displayName)
338                     continue;
339
340                 auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value;
341                 if (!record.displayName)
342                     record.displayName = WTFMove(displayName);
343
344                 record.addCookieHostName(hostName);
345             }
346
347 #if ENABLE(NETSCAPE_PLUGIN_API)
348             for (auto& hostName : websiteData.hostNamesWithPluginData) {
349                 auto displayName = WebsiteDataRecord::displayNameForHostName(hostName);
350                 if (!displayName)
351                     continue;
352
353                 auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value;
354                 if (!record.displayName)
355                     record.displayName = WTFMove(displayName);
356
357                 record.addPluginDataHostName(hostName);
358             }
359 #endif
360
361             for (auto& hostName : websiteData.hostNamesWithHSTSCache) {
362                 auto displayName = WebsiteDataRecord::displayNameForHostName(hostName);
363                 if (!displayName)
364                     continue;
365                 
366                 auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value;
367                 if (!record.displayName)
368                     record.displayName = WTFMove(displayName);
369
370                 record.addHSTSCacheHostname(hostName);
371             }
372
373 #if ENABLE(RESOURCE_LOAD_STATISTICS)
374             for (const auto& domain : websiteData.registrableDomainsWithResourceLoadStatistics) {
375                 auto displayName = WebsiteDataRecord::displayNameForHostName(domain.string());
376                 if (!displayName)
377                     continue;
378
379                 auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value;
380                 if (!record.displayName)
381                     record.displayName = WTFMove(displayName);
382
383                 record.addResourceLoadStatisticsRegistrableDomain(domain);
384             }
385 #endif
386
387             callIfNeeded();
388         }
389
390         void callIfNeeded()
391         {
392             if (pendingCallbacks)
393                 return;
394
395             Vector<WebsiteDataRecord> records;
396             records.reserveInitialCapacity(m_websiteDataRecords.size());
397             for (auto& record : m_websiteDataRecords.values())
398                 records.uncheckedAppend(WTFMove(record));
399
400             auto processRecords = [apply = WTFMove(apply), records = WTFMove(records)] () mutable {
401                 apply(WTFMove(records));
402             };
403
404             if (queue)
405                 queue->dispatch(WTFMove(processRecords));
406             else
407                 RunLoop::main().dispatch(WTFMove(processRecords));
408         }
409
410         const OptionSet<WebsiteDataFetchOption> fetchOptions;
411
412         unsigned pendingCallbacks = 0;
413         RefPtr<WorkQueue> queue;
414         Function<void(Vector<WebsiteDataRecord>)> apply;
415
416         HashMap<String, WebsiteDataRecord> m_websiteDataRecords;
417         Ref<WebsiteDataStore> protectedDataStore;
418     };
419
420     RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(fetchOptions, WTFMove(queue), WTFMove(apply), *this));
421
422 #if ENABLE(VIDEO)
423     if (dataTypes.contains(WebsiteDataType::DiskCache)) {
424         callbackAggregator->addPendingCallback();
425         m_queue->dispatch([mediaCacheDirectory = m_configuration->mediaCacheDirectory().isolatedCopy(), callbackAggregator] {
426             // FIXME: Make HTMLMediaElement::originsInMediaCache return a collection of SecurityOriginDatas.
427             HashSet<RefPtr<WebCore::SecurityOrigin>> origins = WebCore::HTMLMediaElement::originsInMediaCache(mediaCacheDirectory);
428             WebsiteData websiteData;
429             
430             for (auto& origin : origins) {
431                 WebsiteData::Entry entry { origin->data(), WebsiteDataType::DiskCache, 0 };
432                 websiteData.entries.append(WTFMove(entry));
433             }
434             
435             RunLoop::main().dispatch([callbackAggregator, origins = WTFMove(origins), websiteData = WTFMove(websiteData)]() mutable {
436                 callbackAggregator->removePendingCallback(WTFMove(websiteData));
437             });
438         });
439     }
440 #endif
441
442     auto networkProcessAccessType = computeNetworkProcessAccessTypeForDataFetch(dataTypes, !isPersistent());
443     if (networkProcessAccessType != ProcessAccessType::None) {
444         auto pools = networkProcessAccessType == ProcessAccessType::Launch ? ensureProcessPools() : processPools();
445         for (auto& processPool : pools) {
446             switch (networkProcessAccessType) {
447             case ProcessAccessType::OnlyIfLaunched:
448                 if (!processPool->networkProcess())
449                     continue;
450                 break;
451
452             case ProcessAccessType::Launch:
453                 processPool->ensureNetworkProcess(this);
454                 break;
455
456             case ProcessAccessType::None:
457                 ASSERT_NOT_REACHED();
458             }
459
460             callbackAggregator->addPendingCallback();
461             processPool->networkProcess()->fetchWebsiteData(m_sessionID, dataTypes, fetchOptions, [callbackAggregator, processPool](WebsiteData websiteData) {
462                 callbackAggregator->removePendingCallback(WTFMove(websiteData));
463             });
464         }
465     }
466
467     auto webProcessAccessType = computeWebProcessAccessTypeForDataFetch(dataTypes, !isPersistent());
468     if (webProcessAccessType != ProcessAccessType::None) {
469         for (auto& process : processes()) {
470             switch (webProcessAccessType) {
471             case ProcessAccessType::OnlyIfLaunched:
472                 if (process.state() != WebProcessProxy::State::Running)
473                     continue;
474                 break;
475
476             case ProcessAccessType::Launch:
477                 // FIXME: Handle this.
478                 ASSERT_NOT_REACHED();
479                 break;
480
481             case ProcessAccessType::None:
482                 ASSERT_NOT_REACHED();
483             }
484
485             callbackAggregator->addPendingCallback();
486             process.fetchWebsiteData(m_sessionID, dataTypes, [callbackAggregator](WebsiteData websiteData) {
487                 callbackAggregator->removePendingCallback(WTFMove(websiteData));
488             });
489         }
490     }
491
492     if (dataTypes.contains(WebsiteDataType::DeviceIdHashSalt)) {
493         callbackAggregator->addPendingCallback();
494
495         m_deviceIdHashSaltStorage->getDeviceIdHashSaltOrigins([callbackAggregator](auto&& origins) {
496             WebsiteData websiteData;
497
498             while (!origins.isEmpty())
499                 websiteData.entries.append(WebsiteData::Entry { origins.takeAny(), WebsiteDataType::DeviceIdHashSalt, 0 });
500
501             callbackAggregator->removePendingCallback(WTFMove(websiteData));
502         });
503     }
504
505     if (dataTypes.contains(WebsiteDataType::OfflineWebApplicationCache) && isPersistent()) {
506         callbackAggregator->addPendingCallback();
507
508         m_queue->dispatch([fetchOptions, applicationCacheDirectory = m_configuration->applicationCacheDirectory().isolatedCopy(), applicationCacheFlatFileSubdirectoryName = m_configuration->applicationCacheFlatFileSubdirectoryName().isolatedCopy(), callbackAggregator] {
509             auto storage = WebCore::ApplicationCacheStorage::create(applicationCacheDirectory, applicationCacheFlatFileSubdirectoryName);
510
511             WebsiteData websiteData;
512
513             // FIXME: getOriginsWithCache should return a collection of SecurityOriginDatas.
514             auto origins = storage->originsWithCache();
515
516             for (auto& origin : origins) {
517                 uint64_t size = fetchOptions.contains(WebsiteDataFetchOption::ComputeSizes) ? storage->diskUsageForOrigin(origin) : 0;
518                 WebsiteData::Entry entry { origin->data(), WebsiteDataType::OfflineWebApplicationCache, size };
519
520                 websiteData.entries.append(WTFMove(entry));
521             }
522
523             RunLoop::main().dispatch([callbackAggregator, origins = WTFMove(origins), websiteData = WTFMove(websiteData)]() mutable {
524                 callbackAggregator->removePendingCallback(WTFMove(websiteData));
525             });
526         });
527     }
528
529     if (dataTypes.contains(WebsiteDataType::WebSQLDatabases) && isPersistent()) {
530         callbackAggregator->addPendingCallback();
531
532         m_queue->dispatch([webSQLDatabaseDirectory = m_configuration->webSQLDatabaseDirectory().isolatedCopy(), callbackAggregator] {
533             auto origins = WebCore::DatabaseTracker::trackerWithDatabasePath(webSQLDatabaseDirectory)->origins();
534             RunLoop::main().dispatch([callbackAggregator, origins = WTFMove(origins)]() mutable {
535                 WebsiteData websiteData;
536                 for (auto& origin : origins)
537                     websiteData.entries.append(WebsiteData::Entry { WTFMove(origin), WebsiteDataType::WebSQLDatabases, 0 });
538                 callbackAggregator->removePendingCallback(WTFMove(websiteData));
539             });
540         });
541     }
542
543     if (dataTypes.contains(WebsiteDataType::MediaKeys) && isPersistent()) {
544         callbackAggregator->addPendingCallback();
545
546         m_queue->dispatch([mediaKeysStorageDirectory = m_configuration->mediaKeysStorageDirectory().isolatedCopy(), callbackAggregator] {
547             auto origins = mediaKeyOrigins(mediaKeysStorageDirectory);
548
549             RunLoop::main().dispatch([callbackAggregator, origins = WTFMove(origins)]() mutable {
550                 WebsiteData websiteData;
551                 for (auto& origin : origins)
552                     websiteData.entries.append(WebsiteData::Entry { origin, WebsiteDataType::MediaKeys, 0 });
553
554                 callbackAggregator->removePendingCallback(WTFMove(websiteData));
555             });
556         });
557     }
558
559 #if ENABLE(NETSCAPE_PLUGIN_API)
560     if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) {
561         class State {
562         public:
563             static void fetchData(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins)
564             {
565                 new State(WTFMove(callbackAggregator), WTFMove(plugins));
566             }
567
568         private:
569             State(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins)
570                 : m_callbackAggregator(WTFMove(callbackAggregator))
571                 , m_plugins(WTFMove(plugins))
572             {
573                 m_callbackAggregator->addPendingCallback();
574
575                 fetchWebsiteDataForNextPlugin();
576             }
577
578             ~State()
579             {
580                 ASSERT(m_plugins.isEmpty());
581             }
582
583             void fetchWebsiteDataForNextPlugin()
584             {
585                 if (m_plugins.isEmpty()) {
586                     WebsiteData websiteData;
587                     websiteData.hostNamesWithPluginData = WTFMove(m_hostNames);
588
589                     m_callbackAggregator->removePendingCallback(WTFMove(websiteData));
590
591                     delete this;
592                     return;
593                 }
594
595                 auto plugin = m_plugins.takeLast();
596                 PluginProcessManager::singleton().fetchWebsiteData(plugin, m_callbackAggregator->fetchOptions, [this](Vector<String> hostNames) {
597                     for (auto& hostName : hostNames)
598                         m_hostNames.add(WTFMove(hostName));
599                     fetchWebsiteDataForNextPlugin();
600                 });
601             }
602
603             Ref<CallbackAggregator> m_callbackAggregator;
604             Vector<PluginModuleInfo> m_plugins;
605             HashSet<String> m_hostNames;
606         };
607
608         State::fetchData(*callbackAggregator, plugins());
609     }
610 #endif
611
612     callbackAggregator->callIfNeeded();
613 }
614
615 #if ENABLE(RESOURCE_LOAD_STATISTICS)
616 void WebsiteDataStore::fetchDataForRegistrableDomains(OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, const Vector<WebCore::RegistrableDomain>& domains, CompletionHandler<void(Vector<WebsiteDataRecord>&&, HashSet<WebCore::RegistrableDomain>&&)>&& completionHandler)
617 {
618     fetchDataAndApply(dataTypes, fetchOptions, m_queue.copyRef(), [domains = crossThreadCopy(domains), completionHandler = WTFMove(completionHandler)] (auto&& existingDataRecords) mutable {
619         ASSERT(!RunLoop::isMain());
620         
621         Vector<WebsiteDataRecord> matchingDataRecords;
622         HashSet<WebCore::RegistrableDomain> domainsWithMatchingDataRecords;
623         for (auto&& dataRecord : existingDataRecords) {
624             for (auto& domain : domains) {
625                 if (dataRecord.matches(domain)) {
626                     matchingDataRecords.append(WTFMove(dataRecord));
627                     domainsWithMatchingDataRecords.add(domain.isolatedCopy());
628                     break;
629                 }
630             }
631         }
632         RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), matchingDataRecords = WTFMove(matchingDataRecords), domainsWithMatchingDataRecords = WTFMove(domainsWithMatchingDataRecords)] () mutable {
633             completionHandler(WTFMove(matchingDataRecords), WTFMove(domainsWithMatchingDataRecords));
634         });
635     });
636 }
637 #endif
638
639 static ProcessAccessType computeNetworkProcessAccessTypeForDataRemoval(OptionSet<WebsiteDataType> dataTypes, bool isNonPersistentStore)
640 {
641     ProcessAccessType processAccessType = ProcessAccessType::None;
642
643     for (auto dataType : dataTypes) {
644         if (dataType == WebsiteDataType::Cookies) {
645             if (isNonPersistentStore)
646                 processAccessType = std::max(processAccessType, ProcessAccessType::OnlyIfLaunched);
647             else
648                 processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
649         } else if (WebsiteData::ownerProcess(dataType) == WebsiteDataProcessType::Network)
650             return ProcessAccessType::Launch;
651     }
652     
653     return processAccessType;
654 }
655
656 static ProcessAccessType computeWebProcessAccessTypeForDataRemoval(OptionSet<WebsiteDataType> dataTypes, bool isNonPersistentStore)
657 {
658     UNUSED_PARAM(isNonPersistentStore);
659
660     ProcessAccessType processAccessType = ProcessAccessType::None;
661
662     if (dataTypes.contains(WebsiteDataType::MemoryCache))
663         processAccessType = std::max(processAccessType, ProcessAccessType::OnlyIfLaunched);
664
665     return processAccessType;
666 }
667
668 void WebsiteDataStore::removeData(OptionSet<WebsiteDataType> dataTypes, WallTime modifiedSince, Function<void()>&& completionHandler)
669 {
670     struct CallbackAggregator : ThreadSafeRefCounted<CallbackAggregator> {
671         CallbackAggregator(WebsiteDataStore& dataStore, Function<void()>&& completionHandler)
672             : completionHandler(WTFMove(completionHandler))
673             , protectedDataStore(dataStore)
674         {
675             ASSERT(RunLoop::isMain());
676         }
677
678         ~CallbackAggregator()
679         {
680             // Make sure the data store gets destroyed on the main thread even though the CallbackAggregator can get destroyed on a background queue.
681             RunLoop::main().dispatch([protectedDataStore = WTFMove(protectedDataStore)] { });
682         }
683
684         void addPendingCallback()
685         {
686             pendingCallbacks++;
687         }
688
689         void removePendingCallback()
690         {
691             ASSERT(pendingCallbacks);
692             --pendingCallbacks;
693
694             callIfNeeded();
695         }
696
697         void callIfNeeded()
698         {
699             if (!pendingCallbacks)
700                 RunLoop::main().dispatch(WTFMove(completionHandler));
701         }
702
703         unsigned pendingCallbacks = 0;
704         Function<void()> completionHandler;
705         Ref<WebsiteDataStore> protectedDataStore;
706     };
707
708     RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(*this, WTFMove(completionHandler)));
709
710 #if ENABLE(VIDEO)
711     if (dataTypes.contains(WebsiteDataType::DiskCache)) {
712         callbackAggregator->addPendingCallback();
713         m_queue->dispatch([modifiedSince, mediaCacheDirectory = m_configuration->mediaCacheDirectory().isolatedCopy(), callbackAggregator] {
714             WebCore::HTMLMediaElement::clearMediaCache(mediaCacheDirectory, modifiedSince);
715             
716             WTF::RunLoop::main().dispatch([callbackAggregator] {
717                 callbackAggregator->removePendingCallback();
718             });
719         });
720     }
721 #endif
722
723 #if ENABLE(RESOURCE_LOAD_STATISTICS)
724     bool didNotifyNetworkProcessToDeleteWebsiteData = false;
725 #endif
726     auto networkProcessAccessType = computeNetworkProcessAccessTypeForDataRemoval(dataTypes, !isPersistent());
727     if (networkProcessAccessType != ProcessAccessType::None) {
728         auto pools = networkProcessAccessType == ProcessAccessType::Launch ? ensureProcessPools() : processPools();
729         for (auto& processPool : pools) {
730             switch (networkProcessAccessType) {
731             case ProcessAccessType::OnlyIfLaunched:
732                 if (!processPool->networkProcess())
733                     continue;
734                 break;
735
736             case ProcessAccessType::Launch:
737                 processPool->ensureNetworkProcess(this);
738                 break;
739
740             case ProcessAccessType::None:
741                 ASSERT_NOT_REACHED();
742             }
743
744             callbackAggregator->addPendingCallback();
745             processPool->networkProcess()->deleteWebsiteData(m_sessionID, dataTypes, modifiedSince, [callbackAggregator, processPool] {
746                 callbackAggregator->removePendingCallback();
747             });
748 #if ENABLE(RESOURCE_LOAD_STATISTICS)
749             didNotifyNetworkProcessToDeleteWebsiteData = true;
750 #endif
751         }
752     }
753
754     auto webProcessAccessType = computeWebProcessAccessTypeForDataRemoval(dataTypes, !isPersistent());
755     if (webProcessAccessType != ProcessAccessType::None) {
756         for (auto& processPool : processPools()) {
757             // Clear back/forward cache first as processes removed from the back/forward cache will likely
758             // be added to the WebProcess cache.
759             processPool->backForwardCache().removeEntriesForSession(sessionID());
760             processPool->webProcessCache().clearAllProcessesForSession(sessionID());
761         }
762
763         for (auto& process : processes()) {
764             switch (webProcessAccessType) {
765             case ProcessAccessType::OnlyIfLaunched:
766                 if (process.state() != WebProcessProxy::State::Running)
767                     continue;
768                 break;
769
770             case ProcessAccessType::Launch:
771                 // FIXME: Handle this.
772                 ASSERT_NOT_REACHED();
773                 break;
774
775             case ProcessAccessType::None:
776                 ASSERT_NOT_REACHED();
777             }
778
779             callbackAggregator->addPendingCallback();
780             process.deleteWebsiteData(m_sessionID, dataTypes, modifiedSince, [callbackAggregator] {
781                 callbackAggregator->removePendingCallback();
782             });
783         }
784     }
785
786     if (dataTypes.contains(WebsiteDataType::DeviceIdHashSalt) || (dataTypes.contains(WebsiteDataType::Cookies))) {
787         callbackAggregator->addPendingCallback();
788
789         m_deviceIdHashSaltStorage->deleteDeviceIdHashSaltOriginsModifiedSince(modifiedSince, [callbackAggregator] {
790             callbackAggregator->removePendingCallback();
791         });
792     }
793
794     if (dataTypes.contains(WebsiteDataType::OfflineWebApplicationCache) && isPersistent()) {
795         callbackAggregator->addPendingCallback();
796
797         m_queue->dispatch([applicationCacheDirectory = m_configuration->applicationCacheDirectory().isolatedCopy(), applicationCacheFlatFileSubdirectoryName = m_configuration->applicationCacheFlatFileSubdirectoryName().isolatedCopy(), callbackAggregator] {
798             auto storage = WebCore::ApplicationCacheStorage::create(applicationCacheDirectory, applicationCacheFlatFileSubdirectoryName);
799
800             storage->deleteAllCaches();
801
802             WTF::RunLoop::main().dispatch([callbackAggregator] {
803                 callbackAggregator->removePendingCallback();
804             });
805         });
806     }
807
808     if (dataTypes.contains(WebsiteDataType::WebSQLDatabases) && isPersistent()) {
809         callbackAggregator->addPendingCallback();
810
811         m_queue->dispatch([webSQLDatabaseDirectory = m_configuration->webSQLDatabaseDirectory().isolatedCopy(), callbackAggregator, modifiedSince] {
812             WebCore::DatabaseTracker::trackerWithDatabasePath(webSQLDatabaseDirectory)->deleteDatabasesModifiedSince(modifiedSince);
813
814             RunLoop::main().dispatch([callbackAggregator] {
815                 callbackAggregator->removePendingCallback();
816             });
817         });
818     }
819
820     if (dataTypes.contains(WebsiteDataType::MediaKeys) && isPersistent()) {
821         callbackAggregator->addPendingCallback();
822
823         m_queue->dispatch([mediaKeysStorageDirectory = m_configuration->mediaKeysStorageDirectory().isolatedCopy(), callbackAggregator, modifiedSince] {
824             removeMediaKeys(mediaKeysStorageDirectory, modifiedSince);
825
826             RunLoop::main().dispatch([callbackAggregator] {
827                 callbackAggregator->removePendingCallback();
828             });
829         });
830     }
831
832     if (dataTypes.contains(WebsiteDataType::SearchFieldRecentSearches) && isPersistent()) {
833         callbackAggregator->addPendingCallback();
834
835         m_queue->dispatch([modifiedSince, callbackAggregator] {
836             platformRemoveRecentSearches(modifiedSince);
837
838             RunLoop::main().dispatch([callbackAggregator] {
839                 callbackAggregator->removePendingCallback();
840             });
841         });
842     }
843
844 #if ENABLE(NETSCAPE_PLUGIN_API)
845     if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) {
846         class State {
847         public:
848             static void deleteData(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, WallTime modifiedSince)
849             {
850                 new State(WTFMove(callbackAggregator), WTFMove(plugins), modifiedSince);
851             }
852
853         private:
854             State(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, WallTime modifiedSince)
855                 : m_callbackAggregator(WTFMove(callbackAggregator))
856                 , m_plugins(WTFMove(plugins))
857                 , m_modifiedSince(modifiedSince)
858             {
859                 m_callbackAggregator->addPendingCallback();
860
861                 deleteWebsiteDataForNextPlugin();
862             }
863
864             ~State()
865             {
866                 ASSERT(m_plugins.isEmpty());
867             }
868
869             void deleteWebsiteDataForNextPlugin()
870             {
871                 if (m_plugins.isEmpty()) {
872                     m_callbackAggregator->removePendingCallback();
873
874                     delete this;
875                     return;
876                 }
877
878                 auto plugin = m_plugins.takeLast();
879                 PluginProcessManager::singleton().deleteWebsiteData(plugin, m_modifiedSince, [this] {
880                     deleteWebsiteDataForNextPlugin();
881                 });
882             }
883
884             Ref<CallbackAggregator> m_callbackAggregator;
885             Vector<PluginModuleInfo> m_plugins;
886             WallTime m_modifiedSince;
887         };
888
889         State::deleteData(*callbackAggregator, plugins(), modifiedSince);
890     }
891 #endif
892
893 #if ENABLE(RESOURCE_LOAD_STATISTICS)
894     if (dataTypes.contains(WebsiteDataType::ResourceLoadStatistics)) {
895         if (!didNotifyNetworkProcessToDeleteWebsiteData) {
896             for (auto& processPool : processPools()) {
897                 if (auto* process = processPool->networkProcess()) {
898                     callbackAggregator->addPendingCallback();
899                     process->deleteWebsiteData(m_sessionID, dataTypes, modifiedSince, [callbackAggregator] {
900                         callbackAggregator->removePendingCallback();
901                     });
902                 }
903             }
904         }
905
906         callbackAggregator->addPendingCallback();
907         clearResourceLoadStatisticsInWebProcesses([callbackAggregator] {
908             callbackAggregator->removePendingCallback();
909         });
910     }
911 #endif
912
913     // There's a chance that we don't have any pending callbacks. If so, we want to dispatch the completion handler right away.
914     callbackAggregator->callIfNeeded();
915 }
916
917 void WebsiteDataStore::removeData(OptionSet<WebsiteDataType> dataTypes, const Vector<WebsiteDataRecord>& dataRecords, Function<void()>&& completionHandler)
918 {
919     Vector<WebCore::SecurityOriginData> origins;
920
921     for (const auto& dataRecord : dataRecords) {
922         for (auto& origin : dataRecord.origins)
923             origins.append(origin);
924     }
925
926     struct CallbackAggregator : ThreadSafeRefCounted<CallbackAggregator> {
927         CallbackAggregator(WebsiteDataStore& dataStore, Function<void()>&& completionHandler)
928             : completionHandler(WTFMove(completionHandler))
929             , protectedDataStore(dataStore)
930         {
931             ASSERT(RunLoop::isMain());
932         }
933
934         ~CallbackAggregator()
935         {
936             // Make sure the data store gets destroyed on the main thread even though the CallbackAggregator can get destroyed on a background queue.
937             RunLoop::main().dispatch([protectedDataStore = WTFMove(protectedDataStore)] { });
938         }
939
940         void addPendingCallback()
941         {
942             pendingCallbacks++;
943         }
944
945         void removePendingCallback()
946         {
947             ASSERT(pendingCallbacks);
948             --pendingCallbacks;
949
950             callIfNeeded();
951         }
952
953         void callIfNeeded()
954         {
955             if (!pendingCallbacks)
956                 RunLoop::main().dispatch(WTFMove(completionHandler));
957         }
958
959         unsigned pendingCallbacks = 0;
960         Function<void()> completionHandler;
961         Ref<WebsiteDataStore> protectedDataStore;
962     };
963
964     RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(*this, WTFMove(completionHandler)));
965     
966     if (dataTypes.contains(WebsiteDataType::DiskCache)) {
967         HashSet<WebCore::SecurityOriginData> origins;
968         for (const auto& dataRecord : dataRecords) {
969             for (const auto& origin : dataRecord.origins)
970                 origins.add(origin);
971         }
972         
973 #if ENABLE(VIDEO)
974         callbackAggregator->addPendingCallback();
975         m_queue->dispatch([origins = WTFMove(origins), mediaCacheDirectory = m_configuration->mediaCacheDirectory().isolatedCopy(), callbackAggregator] {
976
977             // FIXME: Move SecurityOrigin::toRawString to SecurityOriginData and
978             // make HTMLMediaElement::clearMediaCacheForOrigins take SecurityOriginData.
979             HashSet<RefPtr<WebCore::SecurityOrigin>> securityOrigins;
980             for (auto& origin : origins)
981                 securityOrigins.add(origin.securityOrigin());
982             WebCore::HTMLMediaElement::clearMediaCacheForOrigins(mediaCacheDirectory, securityOrigins);
983             
984             WTF::RunLoop::main().dispatch([callbackAggregator] {
985                 callbackAggregator->removePendingCallback();
986             });
987         });
988 #endif
989     }
990     
991     auto networkProcessAccessType = computeNetworkProcessAccessTypeForDataRemoval(dataTypes, !isPersistent());
992     if (networkProcessAccessType != ProcessAccessType::None) {
993         auto pools = networkProcessAccessType == ProcessAccessType::Launch ? ensureProcessPools() : processPools();
994         for (auto& processPool : pools) {
995             switch (networkProcessAccessType) {
996             case ProcessAccessType::OnlyIfLaunched:
997                 if (!processPool->networkProcess())
998                     continue;
999                 break;
1000
1001             case ProcessAccessType::Launch:
1002                 processPool->ensureNetworkProcess(this);
1003                 break;
1004
1005             case ProcessAccessType::None:
1006                 ASSERT_NOT_REACHED();
1007             }
1008
1009             Vector<String> cookieHostNames;
1010             Vector<String> HSTSCacheHostNames;
1011             Vector<WebCore::RegistrableDomain> registrableDomains;
1012             for (const auto& dataRecord : dataRecords) {
1013                 for (auto& hostName : dataRecord.cookieHostNames)
1014                     cookieHostNames.append(hostName);
1015                 for (auto& hostName : dataRecord.HSTSCacheHostNames)
1016                     HSTSCacheHostNames.append(hostName);
1017 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1018                 for (auto& registrableDomain : dataRecord.resourceLoadStatisticsRegistrableDomains)
1019                     registrableDomains.append(registrableDomain);
1020 #endif
1021             }
1022
1023             callbackAggregator->addPendingCallback();
1024             processPool->networkProcess()->deleteWebsiteDataForOrigins(m_sessionID, dataTypes, origins, cookieHostNames, HSTSCacheHostNames, registrableDomains, [callbackAggregator, processPool] {
1025                 callbackAggregator->removePendingCallback();
1026             });
1027         }
1028     }
1029
1030     auto webProcessAccessType = computeWebProcessAccessTypeForDataRemoval(dataTypes, !isPersistent());
1031     if (webProcessAccessType != ProcessAccessType::None) {
1032         for (auto& process : processes()) {
1033             switch (webProcessAccessType) {
1034             case ProcessAccessType::OnlyIfLaunched:
1035                 if (process.state() != WebProcessProxy::State::Running)
1036                     continue;
1037                 break;
1038
1039             case ProcessAccessType::Launch:
1040                 // FIXME: Handle this.
1041                 ASSERT_NOT_REACHED();
1042                 break;
1043
1044             case ProcessAccessType::None:
1045                 ASSERT_NOT_REACHED();
1046             }
1047
1048             callbackAggregator->addPendingCallback();
1049
1050             process.deleteWebsiteDataForOrigins(m_sessionID, dataTypes, origins, [callbackAggregator] {
1051                 callbackAggregator->removePendingCallback();
1052             });
1053         }
1054     }
1055
1056     if (dataTypes.contains(WebsiteDataType::DeviceIdHashSalt) || (dataTypes.contains(WebsiteDataType::Cookies))) {
1057         callbackAggregator->addPendingCallback();
1058
1059         m_deviceIdHashSaltStorage->deleteDeviceIdHashSaltForOrigins(origins, [callbackAggregator] {
1060             callbackAggregator->removePendingCallback();
1061         });
1062     }
1063
1064     if (dataTypes.contains(WebsiteDataType::OfflineWebApplicationCache) && isPersistent()) {
1065         HashSet<WebCore::SecurityOriginData> origins;
1066         for (const auto& dataRecord : dataRecords) {
1067             for (const auto& origin : dataRecord.origins)
1068                 origins.add(origin);
1069         }
1070
1071         callbackAggregator->addPendingCallback();
1072         m_queue->dispatch([origins = WTFMove(origins), applicationCacheDirectory = m_configuration->applicationCacheDirectory().isolatedCopy(), applicationCacheFlatFileSubdirectoryName = m_configuration->applicationCacheFlatFileSubdirectoryName().isolatedCopy(), callbackAggregator] {
1073             auto storage = WebCore::ApplicationCacheStorage::create(applicationCacheDirectory, applicationCacheFlatFileSubdirectoryName);
1074
1075             for (const auto& origin : origins)
1076                 storage->deleteCacheForOrigin(origin.securityOrigin());
1077
1078             WTF::RunLoop::main().dispatch([callbackAggregator] {
1079                 callbackAggregator->removePendingCallback();
1080             });
1081         });
1082     }
1083
1084     if (dataTypes.contains(WebsiteDataType::WebSQLDatabases) && isPersistent()) {
1085         HashSet<WebCore::SecurityOriginData> origins;
1086         for (const auto& dataRecord : dataRecords) {
1087             for (const auto& origin : dataRecord.origins)
1088                 origins.add(origin);
1089         }
1090
1091         callbackAggregator->addPendingCallback();
1092         m_queue->dispatch([origins = WTFMove(origins), callbackAggregator, webSQLDatabaseDirectory = m_configuration->webSQLDatabaseDirectory().isolatedCopy()] {
1093             auto databaseTracker = WebCore::DatabaseTracker::trackerWithDatabasePath(webSQLDatabaseDirectory);
1094             for (auto& origin : origins)
1095                 databaseTracker->deleteOrigin(origin);
1096             RunLoop::main().dispatch([callbackAggregator] {
1097                 callbackAggregator->removePendingCallback();
1098             });
1099         });
1100     }
1101
1102     if (dataTypes.contains(WebsiteDataType::MediaKeys) && isPersistent()) {
1103         HashSet<WebCore::SecurityOriginData> origins;
1104         for (const auto& dataRecord : dataRecords) {
1105             for (const auto& origin : dataRecord.origins)
1106                 origins.add(origin);
1107         }
1108
1109         callbackAggregator->addPendingCallback();
1110         m_queue->dispatch([mediaKeysStorageDirectory = m_configuration->mediaKeysStorageDirectory().isolatedCopy(), callbackAggregator, origins = WTFMove(origins)] {
1111
1112             removeMediaKeys(mediaKeysStorageDirectory, origins);
1113
1114             RunLoop::main().dispatch([callbackAggregator] {
1115                 callbackAggregator->removePendingCallback();
1116             });
1117         });
1118     }
1119
1120 #if ENABLE(NETSCAPE_PLUGIN_API)
1121     if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) {
1122         Vector<String> hostNames;
1123         for (const auto& dataRecord : dataRecords) {
1124             for (const auto& hostName : dataRecord.pluginDataHostNames)
1125                 hostNames.append(hostName);
1126         }
1127
1128
1129         class State {
1130         public:
1131             static void deleteData(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, Vector<String>&& hostNames)
1132             {
1133                 new State(WTFMove(callbackAggregator), WTFMove(plugins), WTFMove(hostNames));
1134             }
1135
1136         private:
1137             State(Ref<CallbackAggregator>&& callbackAggregator, Vector<PluginModuleInfo>&& plugins, Vector<String>&& hostNames)
1138                 : m_callbackAggregator(WTFMove(callbackAggregator))
1139                 , m_plugins(WTFMove(plugins))
1140                 , m_hostNames(WTFMove(hostNames))
1141             {
1142                 m_callbackAggregator->addPendingCallback();
1143
1144                 deleteWebsiteDataForNextPlugin();
1145             }
1146
1147             ~State()
1148             {
1149                 ASSERT(m_plugins.isEmpty());
1150             }
1151
1152             void deleteWebsiteDataForNextPlugin()
1153             {
1154                 if (m_plugins.isEmpty()) {
1155                     m_callbackAggregator->removePendingCallback();
1156
1157                     delete this;
1158                     return;
1159                 }
1160
1161                 auto plugin = m_plugins.takeLast();
1162                 PluginProcessManager::singleton().deleteWebsiteDataForHostNames(plugin, m_hostNames, [this] {
1163                     deleteWebsiteDataForNextPlugin();
1164                 });
1165             }
1166
1167             Ref<CallbackAggregator> m_callbackAggregator;
1168             Vector<PluginModuleInfo> m_plugins;
1169             Vector<String> m_hostNames;
1170         };
1171
1172         if (!hostNames.isEmpty())
1173             State::deleteData(*callbackAggregator, plugins(), WTFMove(hostNames));
1174     }
1175 #endif
1176
1177     // There's a chance that we don't have any pending callbacks. If so, we want to dispatch the completion handler right away.
1178     callbackAggregator->callIfNeeded();
1179 }
1180
1181 void WebsiteDataStore::setServiceWorkerTimeoutForTesting(Seconds seconds)
1182 {
1183     for (auto& processPool : WebProcessPool::allProcessPools()) {
1184         if (auto* networkProcess = processPool->networkProcess())
1185             networkProcess->sendSync(Messages::NetworkProcess::SetServiceWorkerFetchTimeoutForTesting(seconds), Messages::NetworkProcess::SetServiceWorkerFetchTimeoutForTesting::Reply(), 0);
1186     }
1187 }
1188
1189 void WebsiteDataStore::resetServiceWorkerTimeoutForTesting()
1190 {
1191     for (auto& processPool : WebProcessPool::allProcessPools()) {
1192         if (auto* networkProcess = processPool->networkProcess())
1193             networkProcess->sendSync(Messages::NetworkProcess::ResetServiceWorkerFetchTimeoutForTesting(), Messages::NetworkProcess::ResetServiceWorkerFetchTimeoutForTesting::Reply(), 0);
1194     }
1195 }
1196
1197 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1198 void WebsiteDataStore::setMaxStatisticsEntries(size_t maximumEntryCount, CompletionHandler<void()>&& completionHandler)
1199 {
1200     ASSERT(RunLoop::isMain());
1201
1202     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1203
1204     for (auto& processPool : processPools())
1205         processPool->ensureNetworkProcess().setMaxStatisticsEntries(m_sessionID, maximumEntryCount, [processPool, callbackAggregator] { });
1206 }
1207
1208 void WebsiteDataStore::setPruneEntriesDownTo(size_t pruneTargetCount, CompletionHandler<void()>&& completionHandler)
1209 {
1210     ASSERT(RunLoop::isMain());
1211     
1212     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1213
1214     for (auto& processPool : processPools())
1215         processPool->ensureNetworkProcess().setPruneEntriesDownTo(m_sessionID, pruneTargetCount, [processPool, callbackAggregator] { });
1216 }
1217
1218 void WebsiteDataStore::setGrandfatheringTime(Seconds seconds, CompletionHandler<void()>&& completionHandler)
1219 {
1220     ASSERT(RunLoop::isMain());
1221
1222     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1223
1224     for (auto& processPool : processPools())
1225         processPool->ensureNetworkProcess().setGrandfatheringTime(m_sessionID, seconds, [processPool, callbackAggregator] { });
1226 }
1227
1228 void WebsiteDataStore::setMinimumTimeBetweenDataRecordsRemoval(Seconds seconds, CompletionHandler<void()>&& completionHandler)
1229 {
1230     ASSERT(RunLoop::isMain());
1231
1232     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1233
1234     for (auto& processPool : processPools())
1235         processPool->ensureNetworkProcess().setMinimumTimeBetweenDataRecordsRemoval(m_sessionID, seconds, [processPool, callbackAggregator] { });
1236 }
1237     
1238 void WebsiteDataStore::dumpResourceLoadStatistics(CompletionHandler<void(const String&)>&& completionHandler)
1239 {
1240     ASSERT(RunLoop::isMain());
1241
1242     for (auto& processPool : processPools()) {
1243         if (auto* process = processPool->networkProcess()) {
1244             process->dumpResourceLoadStatistics(m_sessionID, WTFMove(completionHandler));
1245             break;
1246         }
1247     }
1248 }
1249
1250 void WebsiteDataStore::isPrevalentResource(const URL& url, CompletionHandler<void(bool isPrevalent)>&& completionHandler)
1251 {
1252     ASSERT(RunLoop::isMain());
1253     
1254     if (url.protocolIsAbout() || url.isEmpty()) {
1255         completionHandler(false);
1256         return;
1257     }
1258
1259     for (auto& processPool : processPools()) {
1260         if (auto* process = processPool->networkProcess()) {
1261             process->isPrevalentResource(m_sessionID, WebCore::RegistrableDomain { url }, WTFMove(completionHandler));
1262             break;
1263         }
1264     }
1265 }
1266
1267 void WebsiteDataStore::isGrandfathered(const URL& url, CompletionHandler<void(bool isPrevalent)>&& completionHandler)
1268 {
1269     ASSERT(RunLoop::isMain());
1270     
1271     if (url.protocolIsAbout() || url.isEmpty()) {
1272         completionHandler(false);
1273         return;
1274     }
1275
1276     for (auto& processPool : processPools()) {
1277         if (auto* process = processPool->networkProcess()) {
1278             process->isGrandfathered(m_sessionID, WebCore::RegistrableDomain { url }, WTFMove(completionHandler));
1279             break;
1280         }
1281     }
1282 }
1283
1284 void WebsiteDataStore::setPrevalentResource(const URL& url, CompletionHandler<void()>&& completionHandler)
1285 {
1286     ASSERT(RunLoop::isMain());
1287     
1288     if (url.protocolIsAbout() || url.isEmpty()) {
1289         completionHandler();
1290         return;
1291     }
1292     
1293     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1294
1295     for (auto& processPool : ensureProcessPools())
1296         processPool->ensureNetworkProcess().setPrevalentResource(m_sessionID, WebCore::RegistrableDomain { url }, [processPool, callbackAggregator] { });
1297 }
1298
1299 void WebsiteDataStore::setPrevalentResourceForDebugMode(const URL& url, CompletionHandler<void()>&& completionHandler)
1300 {
1301     ASSERT(RunLoop::isMain());
1302     
1303     if (url.protocolIsAbout() || url.isEmpty()) {
1304         completionHandler();
1305         return;
1306     }
1307     
1308     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1309     
1310     for (auto& processPool : processPools()) {
1311         if (auto* process = processPool->networkProcess())
1312             process->setPrevalentResourceForDebugMode(m_sessionID, WebCore::RegistrableDomain { url }, [processPool, callbackAggregator] { });
1313     }
1314 }
1315
1316 void WebsiteDataStore::isVeryPrevalentResource(const URL& url, CompletionHandler<void(bool isVeryPrevalent)>&& completionHandler)
1317 {
1318     ASSERT(RunLoop::isMain());
1319     
1320     if (url.protocolIsAbout() || url.isEmpty()) {
1321         completionHandler(false);
1322         return;
1323     }
1324     
1325     for (auto& processPool : processPools()) {
1326         if (auto* process = processPool->networkProcess()) {
1327             process->isVeryPrevalentResource(m_sessionID, WebCore::RegistrableDomain { url }, WTFMove(completionHandler));
1328             break;
1329         }
1330     }
1331 }
1332
1333 void WebsiteDataStore::setVeryPrevalentResource(const URL& url, CompletionHandler<void()>&& completionHandler)
1334 {
1335     ASSERT(RunLoop::isMain());
1336     
1337     if (url.protocolIsAbout() || url.isEmpty()) {
1338         completionHandler();
1339         return;
1340     }
1341     
1342     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1343     
1344     for (auto& processPool : processPools()) {
1345         if (auto* networkProcess = processPool->networkProcess())
1346             networkProcess->setVeryPrevalentResource(m_sessionID, WebCore::RegistrableDomain { url }, [processPool, callbackAggregator] { });
1347     }
1348 }
1349
1350 void WebsiteDataStore::setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value, CompletionHandler<void()>&& completionHandler)
1351 {
1352     ASSERT(RunLoop::isMain());
1353     
1354     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1355
1356     for (auto& processPool : processPools())
1357         processPool->ensureNetworkProcess().setShouldClassifyResourcesBeforeDataRecordsRemoval(m_sessionID, value, [processPool, callbackAggregator] { });
1358 }
1359
1360 void WebsiteDataStore::setSubframeUnderTopFrameDomain(const URL& subFrameURL, const URL& topFrameURL, CompletionHandler<void()>&& completionHandler)
1361 {
1362     ASSERT(RunLoop::isMain());
1363     
1364     if (subFrameURL.protocolIsAbout() || subFrameURL.isEmpty() || topFrameURL.protocolIsAbout() || topFrameURL.isEmpty()) {
1365         completionHandler();
1366         return;
1367     }
1368
1369     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1370     
1371     for (auto& processPool : processPools()) {
1372         if (auto* process = processPool->networkProcess())
1373             process->setSubframeUnderTopFrameDomain(m_sessionID, WebCore::RegistrableDomain { subFrameURL }, WebCore::RegistrableDomain { topFrameURL }, [processPool, callbackAggregator] { });
1374     }
1375 }
1376
1377 void WebsiteDataStore::isRegisteredAsSubFrameUnder(const URL& subFrameURL, const URL& topFrameURL, CompletionHandler<void(bool)>&& completionHandler)
1378 {
1379     ASSERT(RunLoop::isMain());
1380
1381     for (auto& processPool : processPools()) {
1382         if (auto* process = processPool->networkProcess()) {
1383             process->isRegisteredAsSubFrameUnder(m_sessionID, WebCore::RegistrableDomain { subFrameURL }, WebCore::RegistrableDomain { topFrameURL }, WTFMove(completionHandler));
1384             break;
1385         }
1386     }
1387 }
1388
1389 void WebsiteDataStore::setSubresourceUnderTopFrameDomain(const URL& subresourceURL, const URL& topFrameURL, CompletionHandler<void()>&& completionHandler)
1390 {
1391     ASSERT(RunLoop::isMain());
1392     
1393     if (subresourceURL.protocolIsAbout() || subresourceURL.isEmpty() || topFrameURL.protocolIsAbout() || topFrameURL.isEmpty()) {
1394         completionHandler();
1395         return;
1396     }
1397
1398     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1399     
1400     for (auto& processPool : processPools()) {
1401         if (auto* process = processPool->networkProcess())
1402             process->setSubresourceUnderTopFrameDomain(m_sessionID, WebCore::RegistrableDomain { subresourceURL }, WebCore::RegistrableDomain { topFrameURL }, [processPool, callbackAggregator] { });
1403     }
1404 }
1405
1406 void WebsiteDataStore::isRegisteredAsSubresourceUnder(const URL& subresourceURL, const URL& topFrameURL, CompletionHandler<void(bool)>&& completionHandler)
1407 {
1408     ASSERT(RunLoop::isMain());
1409     
1410     for (auto& processPool : processPools()) {
1411         if (auto* process = processPool->networkProcess()) {
1412             process->isRegisteredAsSubresourceUnder(m_sessionID, WebCore::RegistrableDomain { subresourceURL }, WebCore::RegistrableDomain { topFrameURL }, WTFMove(completionHandler));
1413             return;
1414         }
1415     }
1416     completionHandler(false);
1417 }
1418
1419 void WebsiteDataStore::setSubresourceUniqueRedirectTo(const URL& subresourceURL, const URL& urlRedirectedTo, CompletionHandler<void()>&& completionHandler)
1420 {
1421     ASSERT(RunLoop::isMain());
1422     
1423     if (subresourceURL.protocolIsAbout() || subresourceURL.isEmpty() || urlRedirectedTo.protocolIsAbout() || urlRedirectedTo.isEmpty()) {
1424         completionHandler();
1425         return;
1426     }
1427
1428     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1429     
1430     for (auto& processPool : processPools()) {
1431         if (auto* process = processPool->networkProcess())
1432             process->setSubresourceUniqueRedirectTo(m_sessionID, WebCore::RegistrableDomain { subresourceURL }, WebCore::RegistrableDomain { urlRedirectedTo }, [processPool, callbackAggregator] { });
1433     }
1434 }
1435
1436 void WebsiteDataStore::setSubresourceUniqueRedirectFrom(const URL& subresourceURL, const URL& urlRedirectedFrom, CompletionHandler<void()>&& completionHandler)
1437 {
1438     ASSERT(RunLoop::isMain());
1439     
1440     if (subresourceURL.protocolIsAbout() || subresourceURL.isEmpty() || urlRedirectedFrom.protocolIsAbout() || urlRedirectedFrom.isEmpty()) {
1441         completionHandler();
1442         return;
1443     }
1444
1445     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1446     
1447     for (auto& processPool : processPools()) {
1448         if (auto* process = processPool->networkProcess())
1449             process->setSubresourceUniqueRedirectFrom(m_sessionID, WebCore::RegistrableDomain { subresourceURL }, WebCore::RegistrableDomain { urlRedirectedFrom }, [processPool, callbackAggregator] { });
1450     }
1451 }
1452
1453 void WebsiteDataStore::setTopFrameUniqueRedirectTo(const URL& topFrameURL, const URL& urlRedirectedTo, CompletionHandler<void()>&& completionHandler)
1454 {
1455     ASSERT(RunLoop::isMain());
1456     
1457     if (topFrameURL.protocolIsAbout() || topFrameURL.isEmpty() || urlRedirectedTo.protocolIsAbout() || urlRedirectedTo.isEmpty()) {
1458         completionHandler();
1459         return;
1460     }
1461
1462     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1463     
1464     for (auto& processPool : processPools()) {
1465         if (auto* process = processPool->networkProcess())
1466             process->setTopFrameUniqueRedirectTo(m_sessionID, WebCore::RegistrableDomain { topFrameURL }, WebCore::RegistrableDomain { urlRedirectedTo }, [processPool, callbackAggregator] { });
1467     }
1468 }
1469
1470 void WebsiteDataStore::setTopFrameUniqueRedirectFrom(const URL& topFrameURL, const URL& urlRedirectedFrom, CompletionHandler<void()>&& completionHandler)
1471 {
1472     ASSERT(RunLoop::isMain());
1473     
1474     if (topFrameURL.protocolIsAbout() || topFrameURL.isEmpty() || urlRedirectedFrom.protocolIsAbout() || urlRedirectedFrom.isEmpty()) {
1475         completionHandler();
1476         return;
1477     }
1478
1479     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1480     
1481     for (auto& processPool : processPools()) {
1482         if (auto* process = processPool->networkProcess())
1483             process->setTopFrameUniqueRedirectFrom(m_sessionID, WebCore::RegistrableDomain { topFrameURL }, WebCore::RegistrableDomain { urlRedirectedFrom }, [processPool, callbackAggregator] { });
1484     }
1485 }
1486
1487 void WebsiteDataStore::isRegisteredAsRedirectingTo(const URL& urlRedirectedFrom, const URL& urlRedirectedTo, CompletionHandler<void(bool)>&& completionHandler)
1488 {
1489     ASSERT(RunLoop::isMain());
1490     
1491     for (auto& processPool : processPools()) {
1492         if (auto* process = processPool->networkProcess()) {
1493             process->isRegisteredAsRedirectingTo(m_sessionID, WebCore::RegistrableDomain { urlRedirectedFrom }, WebCore::RegistrableDomain { urlRedirectedTo }, WTFMove(completionHandler));
1494             return;
1495         }
1496     }
1497     completionHandler(false);
1498 }
1499
1500 void WebsiteDataStore::clearPrevalentResource(const URL& url, CompletionHandler<void()>&& completionHandler)
1501 {
1502     ASSERT(RunLoop::isMain());
1503         
1504     if (url.protocolIsAbout() || url.isEmpty()) {
1505         completionHandler();
1506         return;
1507     }
1508
1509     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1510
1511     for (auto& processPool : processPools()) {
1512         if (auto* process = processPool->networkProcess())
1513             process->clearPrevalentResource(m_sessionID, WebCore::RegistrableDomain { url }, [processPool, callbackAggregator] { });
1514     }
1515 }
1516
1517 void WebsiteDataStore::resetParametersToDefaultValues(CompletionHandler<void()>&& completionHandler)
1518 {
1519     ASSERT(RunLoop::isMain());
1520
1521     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1522     
1523     for (auto& processPool : processPools()) {
1524         if (auto* process = processPool->networkProcess())
1525             process->resetParametersToDefaultValues(m_sessionID, [processPool, callbackAggregator] { });
1526     }
1527 }
1528
1529 void WebsiteDataStore::submitTelemetry()
1530 {
1531     ASSERT(RunLoop::isMain());
1532     
1533     for (auto& processPool : processPools()) {
1534         if (auto* process = processPool->networkProcess())
1535             process->submitTelemetry(m_sessionID, [] { });
1536     }
1537 }
1538
1539 void WebsiteDataStore::scheduleClearInMemoryAndPersistent(WallTime modifiedSince, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
1540 {
1541     ASSERT(RunLoop::isMain());
1542     
1543     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1544
1545     for (auto& processPool : processPools()) {
1546         if (auto* process = processPool->networkProcess())
1547             process->scheduleClearInMemoryAndPersistent(m_sessionID, modifiedSince, shouldGrandfather, [processPool, callbackAggregator] { });
1548     }
1549 }
1550
1551 void WebsiteDataStore::getResourceLoadStatisticsDataSummary(CompletionHandler<void(Vector<WebResourceLoadStatisticsStore::ThirdPartyData>&&)>&& completionHandler)
1552 {
1553     ASSERT(RunLoop::isMain());
1554
1555     struct CallbackAggregator : RefCounted<CallbackAggregator> {
1556         CallbackAggregator(CompletionHandler<void(Vector<WebResourceLoadStatisticsStore::ThirdPartyData>&&)>&& completionHandler)
1557             : m_completionHandler(WTFMove(completionHandler))
1558         {
1559             ASSERT(RunLoop::isMain());
1560         };
1561
1562         ~CallbackAggregator()
1563         {
1564             ASSERT(RunLoop::isMain());
1565
1566             m_completionHandler(WTFMove(m_results));
1567         }
1568
1569         void addResult(Vector<WebResourceLoadStatisticsStore::ThirdPartyData>&& results)
1570         {
1571             m_results.appendVector(WTFMove(results));
1572         }
1573
1574         CompletionHandler<void(Vector<WebResourceLoadStatisticsStore::ThirdPartyData>&&)> m_completionHandler;
1575         Vector<WebResourceLoadStatisticsStore::ThirdPartyData> m_results;
1576     };
1577
1578     RefPtr<CallbackAggregator> callbackAggregator = adoptRef(new CallbackAggregator(WTFMove(completionHandler)));
1579
1580     for (auto& processPool : ensureProcessPools()) {
1581         processPool->sendResourceLoadStatisticsDataImmediately([this, protectedThis = makeRef(*this), processPool, callbackAggregator] {
1582             processPool->ensureNetworkProcess(this).getResourceLoadStatisticsDataSummary(m_sessionID, [callbackAggregator, processPool](Vector<WebResourceLoadStatisticsStore::ThirdPartyData>&& data) {
1583                 callbackAggregator->addResult(WTFMove(data));
1584             });
1585         });
1586     }
1587 }
1588
1589 void WebsiteDataStore::scheduleClearInMemoryAndPersistent(ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
1590 {
1591     ASSERT(RunLoop::isMain());
1592     
1593     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1594
1595     for (auto& processPool : processPools()) {
1596         if (auto* process = processPool->networkProcess())
1597             process->scheduleClearInMemoryAndPersistent(m_sessionID, { }, shouldGrandfather, [processPool, callbackAggregator] { });
1598     }
1599 }
1600
1601 void WebsiteDataStore::scheduleCookieBlockingUpdate(CompletionHandler<void()>&& completionHandler)
1602 {
1603     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1604
1605     for (auto& processPool : processPools()) {
1606         if (auto* process = processPool->networkProcess())
1607             process->scheduleCookieBlockingUpdate(m_sessionID, [processPool, callbackAggregator] { });
1608     }
1609 }
1610
1611 void WebsiteDataStore::scheduleStatisticsAndDataRecordsProcessing(CompletionHandler<void()>&& completionHandler)
1612 {
1613     ASSERT(RunLoop::isMain());
1614     
1615     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1616     
1617     for (auto& processPool : processPools()) {
1618         if (auto* process = processPool->networkProcess())
1619             process->scheduleStatisticsAndDataRecordsProcessing(m_sessionID, [processPool, callbackAggregator] { });
1620     }
1621 }
1622
1623 void WebsiteDataStore::statisticsDatabaseHasAllTables(CompletionHandler<void(bool)>&& completionHandler)
1624 {
1625     ASSERT(RunLoop::isMain());
1626
1627     for (auto& processPool : processPools()) {
1628         if (auto* process = processPool->networkProcess()) {
1629             process->statisticsDatabaseHasAllTables(m_sessionID, WTFMove(completionHandler));
1630             return;
1631         }
1632     }
1633
1634     completionHandler(false);
1635 }
1636
1637 void WebsiteDataStore::setLastSeen(const URL& url, Seconds seconds, CompletionHandler<void()>&& completionHandler)
1638 {
1639     if (url.protocolIsAbout() || url.isEmpty()) {
1640         completionHandler();
1641         return;
1642     }
1643
1644     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1645
1646     for (auto& processPool : processPools()) {
1647         if (auto* process = processPool->networkProcess())
1648             process->setLastSeen(m_sessionID, WebCore::RegistrableDomain { url }, seconds, [processPool, callbackAggregator] { });
1649     }
1650 }
1651
1652 void WebsiteDataStore::domainIDExistsInDatabase(int domainID, CompletionHandler<void(bool)>&& completionHandler)
1653 {
1654     ASSERT(RunLoop::isMain());
1655
1656     for (auto& processPool : processPools()) {
1657         if (auto* process = processPool->networkProcess()) {
1658             process->domainIDExistsInDatabase(m_sessionID, domainID, WTFMove(completionHandler));
1659             break;
1660         }
1661     }
1662 }
1663
1664 void WebsiteDataStore::mergeStatisticForTesting(const URL& url, const URL& topFrameUrl1, const URL& topFrameUrl2, Seconds lastSeen, bool hadUserInteraction, Seconds mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, unsigned dataRecordsRemoved, CompletionHandler<void()>&& completionHandler)
1665 {
1666     if (url.protocolIsAbout() || url.isEmpty()) {
1667         completionHandler();
1668         return;
1669     }
1670
1671     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1672
1673     for (auto& processPool : processPools()) {
1674         if (auto* process = processPool->networkProcess())
1675             process->mergeStatisticForTesting(m_sessionID, WebCore::RegistrableDomain { url }, WebCore::RegistrableDomain { topFrameUrl1 }, WebCore::RegistrableDomain { topFrameUrl2 }, lastSeen, hadUserInteraction, mostRecentUserInteraction, isGrandfathered, isPrevalent, isVeryPrevalent, dataRecordsRemoved, [processPool, callbackAggregator] { });
1676     }
1677 }
1678
1679 void WebsiteDataStore::insertExpiredStatisticForTesting(const URL& url, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, CompletionHandler<void()>&& completionHandler)
1680 {
1681     if (url.protocolIsAbout() || url.isEmpty()) {
1682         completionHandler();
1683         return;
1684     }
1685
1686     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1687
1688     for (auto& processPool : processPools()) {
1689         if (auto* process = processPool->networkProcess())
1690             process->insertExpiredStatisticForTesting(m_sessionID, WebCore::RegistrableDomain { url }, hadUserInteraction, isScheduledForAllButCookieDataRemoval, isPrevalent, [processPool, callbackAggregator] { });
1691     }
1692 }
1693
1694 void WebsiteDataStore::setNotifyPagesWhenDataRecordsWereScanned(bool value, CompletionHandler<void()>&& completionHandler)
1695 {
1696     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1697
1698     for (auto& processPool : processPools())
1699         processPool->ensureNetworkProcess().setNotifyPagesWhenDataRecordsWereScanned(m_sessionID, value, [processPool, callbackAggregator] { });
1700 }
1701
1702 void WebsiteDataStore::setIsRunningResourceLoadStatisticsTest(bool value, CompletionHandler<void()>&& completionHandler)
1703 {
1704     useExplicitITPState();
1705     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1706     
1707     for (auto& processPool : processPools())
1708         processPool->ensureNetworkProcess().setIsRunningResourceLoadStatisticsTest(m_sessionID, value, [processPool, callbackAggregator] { });
1709 }
1710
1711 void WebsiteDataStore::getAllStorageAccessEntries(WebPageProxyIdentifier pageID, CompletionHandler<void(Vector<String>&& domains)>&& completionHandler)
1712 {
1713     auto* webPage = WebProcessProxy::webPage(pageID);
1714     if (!webPage) {
1715         completionHandler({ });
1716         return;
1717     }
1718
1719     webPage->process().processPool().ensureNetworkProcess().getAllStorageAccessEntries(m_sessionID, WTFMove(completionHandler));
1720 }
1721
1722
1723 void WebsiteDataStore::setTimeToLiveUserInteraction(Seconds seconds, CompletionHandler<void()>&& completionHandler)
1724 {
1725     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1726     
1727     for (auto& processPool : processPools())
1728         processPool->ensureNetworkProcess().setTimeToLiveUserInteraction(m_sessionID, seconds, [callbackAggregator] { });
1729 }
1730
1731 void WebsiteDataStore::logUserInteraction(const URL& url, CompletionHandler<void()>&& completionHandler)
1732 {
1733     ASSERT(RunLoop::isMain());
1734     
1735     if (url.protocolIsAbout() || url.isEmpty()) {
1736         completionHandler();
1737         return;
1738     }
1739     
1740     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1741
1742     for (auto& processPool : processPools()) {
1743         if (auto* process = processPool->networkProcess())
1744             process->logUserInteraction(m_sessionID, WebCore::RegistrableDomain { url }, [callbackAggregator] { });
1745     }
1746 }
1747
1748 void WebsiteDataStore::hasHadUserInteraction(const URL& url, CompletionHandler<void(bool)>&& completionHandler)
1749 {
1750     ASSERT(RunLoop::isMain());
1751     
1752     if (url.protocolIsAbout() || url.isEmpty()) {
1753         completionHandler(false);
1754         return;
1755     }
1756     
1757     for (auto& processPool : processPools()) {
1758         if (auto* process = processPool->networkProcess()) {
1759             process->hasHadUserInteraction(m_sessionID, WebCore::RegistrableDomain { url }, WTFMove(completionHandler));
1760             return;
1761         }
1762     }
1763     completionHandler(false);
1764 }
1765
1766 void WebsiteDataStore::isRelationshipOnlyInDatabaseOnce(const URL& subUrl, const URL& topUrl, CompletionHandler<void(bool)>&& completionHandler)
1767 {
1768     ASSERT(RunLoop::isMain());
1769     
1770     if (subUrl.protocolIsAbout() || subUrl.isEmpty() || topUrl.protocolIsAbout() || topUrl.isEmpty()) {
1771         completionHandler(false);
1772         return;
1773     }
1774     
1775     for (auto& processPool : processPools()) {
1776         if (auto* process = processPool->networkProcess()) {
1777             process->isRelationshipOnlyInDatabaseOnce(m_sessionID, WebCore::RegistrableDomain { subUrl }, WebCore::RegistrableDomain { topUrl }, WTFMove(completionHandler));
1778             return;
1779         }
1780     }
1781     completionHandler(false);
1782 }
1783
1784 void WebsiteDataStore::clearUserInteraction(const URL& url, CompletionHandler<void()>&& completionHandler)
1785 {
1786     ASSERT(RunLoop::isMain());
1787     
1788     if (url.protocolIsAbout() || url.isEmpty()) {
1789         completionHandler();
1790         return;
1791     }
1792     
1793     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1794
1795     for (auto& processPool : processPools()) {
1796         if (auto* process = processPool->networkProcess())
1797             process->clearUserInteraction(m_sessionID, WebCore::RegistrableDomain { url }, [callbackAggregator] { });
1798     }
1799 }
1800
1801 void WebsiteDataStore::setGrandfathered(const URL& url, bool isGrandfathered, CompletionHandler<void()>&& completionHandler)
1802 {
1803     ASSERT(RunLoop::isMain());
1804     
1805     if (url.protocolIsAbout() || url.isEmpty()) {
1806         completionHandler();
1807         return;
1808     }
1809     
1810     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1811     
1812     for (auto& processPool : processPools()) {
1813         if (auto* process = processPool->networkProcess())
1814             process->setGrandfathered(m_sessionID, WebCore::RegistrableDomain { url }, isGrandfathered, [callbackAggregator] { });
1815     }
1816 }
1817
1818 void WebsiteDataStore::setUseITPDatabase(bool value, CompletionHandler<void()>&& completionHandler)
1819 {
1820     ASSERT(RunLoop::isMain());
1821     
1822     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1823     
1824     for (auto& processPool : processPools()) {
1825         if (auto* process = processPool->networkProcess())
1826             process->setUseITPDatabase(m_sessionID, value, [callbackAggregator] { });
1827     }
1828 }
1829
1830 void WebsiteDataStore::setCrossSiteLoadWithLinkDecorationForTesting(const URL& fromURL, const URL& toURL, CompletionHandler<void()>&& completionHandler)
1831 {
1832     ASSERT(RunLoop::isMain());
1833     
1834     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1835     
1836     for (auto& processPool : processPools()) {
1837         if (auto* process = processPool->networkProcess())
1838             process->setCrossSiteLoadWithLinkDecorationForTesting(m_sessionID, WebCore::RegistrableDomain { fromURL }, WebCore::RegistrableDomain { toURL }, [processPool, callbackAggregator] { });
1839     }
1840 }
1841
1842 void WebsiteDataStore::resetCrossSiteLoadsWithLinkDecorationForTesting(CompletionHandler<void()>&& completionHandler)
1843 {
1844     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1845     
1846     for (auto& processPool : processPools()) {
1847         if (auto* networkProcess = processPool->networkProcess())
1848             networkProcess->resetCrossSiteLoadsWithLinkDecorationForTesting(m_sessionID, [callbackAggregator] { });
1849     }
1850 }
1851
1852 void WebsiteDataStore::deleteCookiesForTesting(const URL& url, bool includeHttpOnlyCookies, CompletionHandler<void()>&& completionHandler)
1853 {
1854     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1855     
1856     for (auto& processPool : processPools()) {
1857         if (auto* networkProcess = processPool->networkProcess())
1858             networkProcess->deleteCookiesForTesting(m_sessionID, WebCore::RegistrableDomain { url }, includeHttpOnlyCookies, [callbackAggregator] { });
1859     }
1860 }
1861
1862 void WebsiteDataStore::hasLocalStorageForTesting(const URL& url, CompletionHandler<void(bool)>&& completionHandler) const
1863 {
1864     for (auto& processPool : processPools()) {
1865         if (auto* networkProcess = processPool->networkProcess()) {
1866             networkProcess->hasLocalStorage(m_sessionID, WebCore::RegistrableDomain { url }, WTFMove(completionHandler));
1867             return;
1868         }
1869     }
1870     completionHandler(false);
1871 }
1872
1873 void WebsiteDataStore::hasIsolatedSessionForTesting(const URL& url, CompletionHandler<void(bool)>&& completionHandler) const
1874 {
1875     for (auto& processPool : processPools()) {
1876         if (auto* networkProcess = processPool->networkProcess()) {
1877             networkProcess->hasIsolatedSession(m_sessionID, WebCore::RegistrableDomain { url }, WTFMove(completionHandler));
1878             return;
1879         }
1880     }
1881     completionHandler(false);
1882 }
1883
1884 void WebsiteDataStore::setResourceLoadStatisticsShouldDowngradeReferrerForTesting(bool enabled, CompletionHandler<void()>&& completionHandler)
1885 {
1886     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1887     
1888     for (auto& processPool : processPools()) {
1889         if (auto* networkProcess = processPool->networkProcess())
1890             networkProcess->setShouldDowngradeReferrerForTesting(enabled, [callbackAggregator] { });
1891     }
1892 }
1893
1894 #if !PLATFORM(COCOA)
1895 WebCore::ThirdPartyCookieBlockingMode WebsiteDataStore::thirdPartyCookieBlockingMode() const
1896 {
1897     if (!m_thirdPartyCookieBlockingMode)
1898         m_thirdPartyCookieBlockingMode = WebCore::ThirdPartyCookieBlockingMode::All;
1899     return *m_thirdPartyCookieBlockingMode;
1900 }
1901 #endif
1902
1903 void WebsiteDataStore::setResourceLoadStatisticsShouldBlockThirdPartyCookiesForTesting(bool enabled, bool onlyOnSitesWithoutUserInteraction, CompletionHandler<void()>&& completionHandler)
1904 {
1905     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1906     WebCore::ThirdPartyCookieBlockingMode blockingMode = WebCore::ThirdPartyCookieBlockingMode::OnlyAccordingToPerDomainPolicy;
1907     if (enabled)
1908         blockingMode = onlyOnSitesWithoutUserInteraction ? WebCore::ThirdPartyCookieBlockingMode::AllOnSitesWithoutUserInteraction : WebCore::ThirdPartyCookieBlockingMode::All;
1909     setThirdPartyCookieBlockingMode(blockingMode, WTFMove(completionHandler));
1910 }
1911
1912 void WebsiteDataStore::setThirdPartyCookieBlockingMode(WebCore::ThirdPartyCookieBlockingMode blockingMode, CompletionHandler<void()>&& completionHandler)
1913 {
1914     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1915
1916     if (thirdPartyCookieBlockingMode() != blockingMode) {
1917         m_thirdPartyCookieBlockingMode = blockingMode;
1918         for (auto& webProcess : processes())
1919             webProcess.setThirdPartyCookieBlockingMode(blockingMode, [callbackAggregator] { });
1920     }
1921
1922     for (auto& processPool : processPools()) {
1923         if (auto* networkProcess = processPool->networkProcess())
1924             networkProcess->setThirdPartyCookieBlockingMode(m_sessionID, blockingMode, [callbackAggregator] { });
1925     }
1926 }
1927
1928 void WebsiteDataStore::setResourceLoadStatisticsShouldEnbleSameSiteStrictEnforcementForTesting(bool enabled, CompletionHandler<void()>&& completionHandler)
1929 {
1930     auto flag = enabled ? WebCore::SameSiteStrictEnforcementEnabled::Yes : WebCore::SameSiteStrictEnforcementEnabled::No;
1931
1932     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1933     for (auto& processPool : processPools()) {
1934         if (auto* networkProcess = processPool->networkProcess())
1935             networkProcess->setShouldEnbleSameSiteStrictEnforcementForTesting(m_sessionID, flag, [callbackAggregator] { });
1936     }
1937 }
1938
1939 void WebsiteDataStore::setResourceLoadStatisticsFirstPartyWebsiteDataRemovalModeForTesting(bool enabled, CompletionHandler<void()>&& completionHandler)
1940 {
1941     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1942     auto mode = enabled ? WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies : WebCore::FirstPartyWebsiteDataRemovalMode::None;
1943
1944     for (auto& processPool : processPools()) {
1945         if (auto* networkProcess = processPool->networkProcess())
1946             networkProcess->setFirstPartyWebsiteDataRemovalModeForTesting(m_sessionID, mode, [callbackAggregator] { });
1947     }
1948 }
1949
1950 void WebsiteDataStore::setResourceLoadStatisticsToSameSiteStrictCookiesForTesting(const URL& url, CompletionHandler<void()>&& completionHandler)
1951 {
1952     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1953
1954     for (auto& processPool : processPools()) {
1955         if (auto* networkProcess = processPool->networkProcess())
1956             networkProcess->setToSameSiteStrictCookiesForTesting(m_sessionID, WebCore::RegistrableDomain { url }, [callbackAggregator] { });
1957     }
1958 }
1959
1960 void WebsiteDataStore::setResourceLoadStatisticsFirstPartyHostCNAMEDomainForTesting(const URL& firstPartyURL, const URL& cnameURL, CompletionHandler<void()>&& completionHandler)
1961 {
1962     if (cnameURL.host() != "testwebkit.org" && cnameURL.host() != "3rdpartytestwebkit.org") {
1963         completionHandler();
1964         return;
1965     }
1966
1967     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1968
1969     for (auto& processPool : processPools())
1970         processPool->ensureNetworkProcess().setFirstPartyHostCNAMEDomainForTesting(m_sessionID, firstPartyURL.host().toString(), WebCore::RegistrableDomain { cnameURL }, [callbackAggregator] { });
1971 }
1972
1973 void WebsiteDataStore::setResourceLoadStatisticsThirdPartyCNAMEDomainForTesting(const URL& cnameURL, CompletionHandler<void()>&& completionHandler)
1974 {
1975     if (cnameURL.host() != "testwebkit.org" && cnameURL.host() != "3rdpartytestwebkit.org") {
1976         completionHandler();
1977         return;
1978     }
1979
1980     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1981
1982     for (auto& processPool : processPools())
1983         processPool->ensureNetworkProcess().setThirdPartyCNAMEDomainForTesting(m_sessionID, WebCore::RegistrableDomain { cnameURL }, [callbackAggregator] { });
1984 }
1985 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
1986
1987 void WebsiteDataStore::syncLocalStorage(CompletionHandler<void()>&& completionHandler)
1988 {
1989     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
1990     for (auto& processPool : processPools()) {
1991         if (auto* networkProcess = processPool->networkProcess())
1992             networkProcess->sendWithAsyncReply(Messages::NetworkProcess::SyncLocalStorage(), [callbackAggregator] { });
1993     }
1994 }
1995
1996 void WebsiteDataStore::setCacheMaxAgeCapForPrevalentResources(Seconds seconds, CompletionHandler<void()>&& completionHandler)
1997 {
1998 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1999     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2000     
2001     for (auto& processPool : processPools())
2002         processPool->ensureNetworkProcess().setCacheMaxAgeCapForPrevalentResources(m_sessionID, seconds, [callbackAggregator] { });
2003 #else
2004     UNUSED_PARAM(seconds);
2005     completionHandler();
2006 #endif
2007 }
2008
2009 void WebsiteDataStore::resetCacheMaxAgeCapForPrevalentResources(CompletionHandler<void()>&& completionHandler)
2010 {
2011 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2012     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2013     
2014     for (auto& processPool : processPools()) {
2015         if (auto* networkProcess = processPool->networkProcess())
2016             networkProcess->resetCacheMaxAgeCapForPrevalentResources(m_sessionID, [callbackAggregator] { });
2017     }
2018 #else
2019     completionHandler();
2020 #endif
2021 }
2022
2023 bool WebsiteDataStore::isAssociatedProcessPool(WebProcessPool& processPool) const
2024 {
2025     if (auto* processPoolDataStore = processPool.websiteDataStore())
2026         return processPoolDataStore == this;
2027     if (auto* networkProcessProxy = processPool.networkProcess())
2028         return networkProcessProxy->hasSession(m_sessionID);
2029     return false;
2030 }
2031
2032 HashSet<RefPtr<WebProcessPool>> WebsiteDataStore::processPools(size_t limit) const
2033 {
2034     HashSet<RefPtr<WebProcessPool>> processPools;
2035     for (auto& process : processes()) {
2036         if (auto* processPool = process.processPoolIfExists()) {
2037             processPools.add(processPool);
2038             if (processPools.size() == limit)
2039                 break;
2040         }
2041     }
2042
2043     if (processPools.isEmpty()) {
2044         // Check if we're one of the legacy data stores.
2045         for (auto& processPool : WebProcessPool::allProcessPools()) {
2046             if (!isAssociatedProcessPool(*processPool))
2047                 continue;
2048
2049             processPools.add(processPool);
2050             if (processPools.size() == limit)
2051                 break;
2052         }
2053     }
2054
2055     return processPools;
2056 }
2057
2058 HashSet<RefPtr<WebProcessPool>> WebsiteDataStore::ensureProcessPools() const
2059 {
2060     auto processPools = this->processPools();
2061     if (processPools.isEmpty())
2062         processPools.add(WebProcessPool::create(API::ProcessPoolConfiguration::create()));
2063     return processPools;
2064 }
2065
2066 #if ENABLE(NETSCAPE_PLUGIN_API)
2067 Vector<PluginModuleInfo> WebsiteDataStore::plugins() const
2068 {
2069     Vector<PluginModuleInfo> plugins;
2070
2071     for (auto& processPool : ensureProcessPools()) {
2072         for (auto& plugin : processPool->pluginInfoStore().plugins())
2073             plugins.append(plugin);
2074     }
2075
2076     return plugins;
2077 }
2078 #endif
2079
2080 static String computeMediaKeyFile(const String& mediaKeyDirectory)
2081 {
2082     return FileSystem::pathByAppendingComponent(mediaKeyDirectory, "SecureStop.plist");
2083 }
2084
2085 void WebsiteDataStore::allowSpecificHTTPSCertificateForHost(const WebCertificateInfo* certificate, const String& host)
2086 {
2087     for (auto& processPool : processPools())
2088         processPool->ensureNetworkProcess().send(Messages::NetworkProcess::AllowSpecificHTTPSCertificateForHost(certificate->certificateInfo(), host), 0);
2089 }
2090
2091 Vector<WebCore::SecurityOriginData> WebsiteDataStore::mediaKeyOrigins(const String& mediaKeysStorageDirectory)
2092 {
2093     ASSERT(!mediaKeysStorageDirectory.isEmpty());
2094
2095     Vector<WebCore::SecurityOriginData> origins;
2096
2097     for (const auto& originPath : FileSystem::listDirectory(mediaKeysStorageDirectory, "*")) {
2098         auto mediaKeyFile = computeMediaKeyFile(originPath);
2099         if (!FileSystem::fileExists(mediaKeyFile))
2100             continue;
2101
2102         auto mediaKeyIdentifier = FileSystem::pathGetFileName(originPath);
2103
2104         if (auto securityOrigin = WebCore::SecurityOriginData::fromDatabaseIdentifier(mediaKeyIdentifier))
2105             origins.append(*securityOrigin);
2106     }
2107
2108     return origins;
2109 }
2110
2111 void WebsiteDataStore::removeMediaKeys(const String& mediaKeysStorageDirectory, WallTime modifiedSince)
2112 {
2113     ASSERT(!mediaKeysStorageDirectory.isEmpty());
2114
2115     for (const auto& mediaKeyDirectory : FileSystem::listDirectory(mediaKeysStorageDirectory, "*")) {
2116         auto mediaKeyFile = computeMediaKeyFile(mediaKeyDirectory);
2117
2118         auto modificationTime = FileSystem::getFileModificationTime(mediaKeyFile);
2119         if (!modificationTime)
2120             continue;
2121
2122         if (modificationTime.value() < modifiedSince)
2123             continue;
2124
2125         FileSystem::deleteFile(mediaKeyFile);
2126         FileSystem::deleteEmptyDirectory(mediaKeyDirectory);
2127     }
2128 }
2129
2130 void WebsiteDataStore::removeMediaKeys(const String& mediaKeysStorageDirectory, const HashSet<WebCore::SecurityOriginData>& origins)
2131 {
2132     ASSERT(!mediaKeysStorageDirectory.isEmpty());
2133
2134     for (const auto& origin : origins) {
2135         auto mediaKeyDirectory = FileSystem::pathByAppendingComponent(mediaKeysStorageDirectory, origin.databaseIdentifier());
2136         auto mediaKeyFile = computeMediaKeyFile(mediaKeyDirectory);
2137
2138         FileSystem::deleteFile(mediaKeyFile);
2139         FileSystem::deleteEmptyDirectory(mediaKeyDirectory);
2140     }
2141 }
2142
2143 bool WebsiteDataStore::resourceLoadStatisticsEnabled() const
2144 {
2145 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2146     return m_resourceLoadStatisticsEnabled;
2147 #else
2148     return false;
2149 #endif
2150 }
2151
2152 bool WebsiteDataStore::resourceLoadStatisticsDebugMode() const
2153 {
2154 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2155     return m_resourceLoadStatisticsDebugMode;
2156 #else
2157     return false;
2158 #endif
2159 }
2160
2161 void WebsiteDataStore::setResourceLoadStatisticsEnabled(bool enabled)
2162 {
2163 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2164     if (enabled == resourceLoadStatisticsEnabled())
2165         return;
2166
2167     if (enabled) {
2168         m_resourceLoadStatisticsEnabled = true;
2169         
2170         resolveDirectoriesIfNecessary();
2171         
2172         for (auto& processPool : processPools()) {
2173             processPool->sendToNetworkingProcess(Messages::NetworkProcess::SetResourceLoadStatisticsEnabled(m_sessionID, true));
2174             processPool->sendToAllProcessesForSession(Messages::WebProcess::SetResourceLoadStatisticsEnabled(true), m_sessionID);
2175         }
2176         return;
2177     }
2178
2179     for (auto& processPool : processPools()) {
2180         processPool->sendToNetworkingProcess(Messages::NetworkProcess::SetResourceLoadStatisticsEnabled(m_sessionID, false));
2181         processPool->sendToAllProcessesForSession(Messages::WebProcess::SetResourceLoadStatisticsEnabled(false), m_sessionID);
2182     }
2183
2184     m_resourceLoadStatisticsEnabled = false;
2185 #else
2186     UNUSED_PARAM(enabled);
2187 #endif
2188 }
2189
2190 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2191 void WebsiteDataStore::setStatisticsTestingCallback(Function<void(const String&)>&& callback)
2192 {
2193     if (callback) {
2194         for (auto& processPool : processPools())
2195             processPool->sendToNetworkingProcess(Messages::NetworkProcess::SetResourceLoadStatisticsLogTestingEvent(true));
2196     }
2197     
2198     m_statisticsTestingCallback = WTFMove(callback);
2199 }
2200 #endif
2201
2202 void WebsiteDataStore::setResourceLoadStatisticsDebugMode(bool enabled)
2203 {
2204     setResourceLoadStatisticsDebugMode(enabled, []() { });
2205 }
2206
2207 void WebsiteDataStore::setResourceLoadStatisticsDebugMode(bool enabled, CompletionHandler<void()>&& completionHandler)
2208 {
2209 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2210     m_resourceLoadStatisticsDebugMode = enabled;
2211
2212     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2213     
2214     for (auto& processPool : processPools())
2215         processPool->ensureNetworkProcess().setResourceLoadStatisticsDebugMode(m_sessionID, enabled, [callbackAggregator] { });
2216 #else
2217     UNUSED_PARAM(enabled);
2218     UNUSED_PARAM(completionHandler);
2219 #endif
2220 }
2221
2222 void WebsiteDataStore::isResourceLoadStatisticsEphemeral(CompletionHandler<void(bool)>&& completionHandler) const
2223 {
2224 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2225     if (!resourceLoadStatisticsEnabled() || !m_sessionID.isEphemeral()) {
2226         completionHandler(false);
2227         return;
2228     }
2229
2230     for (auto& processPool : processPools()) {
2231         if (auto* networkProcess = processPool->networkProcess()) {
2232             networkProcess->isResourceLoadStatisticsEphemeral(m_sessionID, WTFMove(completionHandler));
2233             return;
2234         }
2235     }
2236 #endif
2237     completionHandler(false);
2238 }
2239
2240 void WebsiteDataStore::setAdClickAttributionDebugMode(bool enabled)
2241 {
2242     for (auto& processPool : processPools())
2243         processPool->ensureNetworkProcess().setAdClickAttributionDebugMode(enabled);
2244 }
2245
2246 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2247 void WebsiteDataStore::logTestingEvent(const String& event)
2248 {
2249     ASSERT(RunLoop::isMain());
2250     
2251     if (m_statisticsTestingCallback)
2252         m_statisticsTestingCallback(event);
2253 }
2254
2255 void WebsiteDataStore::clearResourceLoadStatisticsInWebProcesses(CompletionHandler<void()>&& callback)
2256 {
2257     if (resourceLoadStatisticsEnabled()) {
2258         for (auto& processPool : processPools())
2259             processPool->sendToAllProcessesForSession(Messages::WebProcess::ClearResourceLoadStatistics(), m_sessionID);
2260     }
2261     callback();
2262 }
2263 #endif
2264
2265 Vector<WebCore::Cookie> WebsiteDataStore::pendingCookies() const
2266 {
2267     return copyToVector(m_pendingCookies);
2268 }
2269
2270 void WebsiteDataStore::addPendingCookie(const WebCore::Cookie& cookie)
2271 {
2272     m_pendingCookies.removeIf([&cookie](auto& pendingCookie) {
2273         return pendingCookie.isKeyEqual(cookie);
2274     });
2275     m_pendingCookies.add(cookie);
2276 }
2277
2278 void WebsiteDataStore::removePendingCookie(const WebCore::Cookie& cookie)
2279 {
2280     m_pendingCookies.remove(cookie);
2281 }
2282     
2283 void WebsiteDataStore::clearPendingCookies()
2284 {
2285     m_pendingCookies.clear();
2286 }
2287
2288 void WebsiteDataStore::flushCookies(CompletionHandler<void()>&& completionHandler)
2289 {
2290     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2291     for (auto processPool : WebProcessPool::allProcessPools())
2292         processPool->flushCookies(sessionID(), [callbackAggregator] { });
2293 }
2294
2295 void WebsiteDataStore::setAllowsAnySSLCertificateForWebSocket(bool allows)
2296 {
2297     for (auto processPool : WebProcessPool::allProcessPools()) {
2298         if (auto* networkProcess = processPool->networkProcess())
2299             networkProcess->sendSync(Messages::NetworkProcess::SetAllowsAnySSLCertificateForWebSocket(allows), Messages::NetworkProcess::SetAllowsAnySSLCertificateForWebSocket::Reply(), 0);
2300     }
2301 }
2302
2303 void WebsiteDataStore::clearCachedCredentials()
2304 {
2305     for (auto processPool : WebProcessPool::allProcessPools())
2306         processPool->clearCachedCredentials(sessionID());
2307 }
2308
2309 void WebsiteDataStore::dispatchOnQueue(Function<void()>&& function)
2310 {
2311     m_queue->dispatch(WTFMove(function));
2312 }
2313
2314 uint64_t WebsiteDataStore::perThirdPartyOriginStorageQuota() const
2315 {
2316     // FIXME: Consider whether allowing to set a perThirdPartyOriginStorageQuota from a WebsiteDataStore.
2317     return WebCore::StorageQuotaManager::defaultThirdPartyQuotaFromPerOriginQuota(perOriginStorageQuota());
2318 }
2319
2320 void WebsiteDataStore::setCacheModelSynchronouslyForTesting(CacheModel cacheModel)
2321 {
2322     for (auto processPool : WebProcessPool::allProcessPools())
2323         processPool->setCacheModelSynchronouslyForTesting(cacheModel);
2324 }
2325
2326 WebsiteDataStoreParameters WebsiteDataStore::parameters()
2327 {
2328     WebsiteDataStoreParameters parameters;
2329
2330     resolveDirectoriesIfNecessary();
2331
2332     parameters.pendingCookies = pendingCookies();
2333
2334     auto resourceLoadStatisticsDirectory = m_configuration->resourceLoadStatisticsDirectory();
2335     SandboxExtension::Handle resourceLoadStatisticsDirectoryHandle;
2336     if (!resourceLoadStatisticsDirectory.isEmpty())
2337         SandboxExtension::createHandleForReadWriteDirectory(resourceLoadStatisticsDirectory, resourceLoadStatisticsDirectoryHandle);
2338
2339     auto networkCacheDirectory = resolvedNetworkCacheDirectory();
2340     SandboxExtension::Handle networkCacheDirectoryExtensionHandle;
2341     if (!networkCacheDirectory.isEmpty())
2342         SandboxExtension::createHandleForReadWriteDirectory(networkCacheDirectory, networkCacheDirectoryExtensionHandle);
2343
2344     auto hstsStorageDirectory = resolvedHSTSStorageDirectory();
2345     SandboxExtension::Handle hstsStorageDirectoryExtensionHandle;
2346     if (!hstsStorageDirectory.isEmpty())
2347         SandboxExtension::createHandleForReadWriteDirectory(hstsStorageDirectory, hstsStorageDirectoryExtensionHandle);
2348
2349     bool shouldIncludeLocalhostInResourceLoadStatistics = false;
2350     bool enableResourceLoadStatisticsDebugMode = false;
2351     auto firstPartyWebsiteDataRemovalMode = WebCore::FirstPartyWebsiteDataRemovalMode::AllButCookies;
2352     WebCore::RegistrableDomain standaloneApplicationDomain;
2353     HashSet<WebCore::RegistrableDomain> appBoundDomains;
2354 #if ENABLE(APP_BOUND_DOMAINS)
2355     if (isAppBoundITPRelaxationEnabled)
2356         appBoundDomains = appBoundDomainsIfInitialized().valueOr(HashSet<WebCore::RegistrableDomain> { });
2357 #endif
2358     WebCore::RegistrableDomain resourceLoadStatisticsManualPrevalentResource;
2359     ResourceLoadStatisticsParameters resourceLoadStatisticsParameters = {
2360         WTFMove(resourceLoadStatisticsDirectory),
2361         WTFMove(resourceLoadStatisticsDirectoryHandle),
2362         resourceLoadStatisticsEnabled(),
2363 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2364         isItpStateExplicitlySet(),
2365         hasStatisticsTestingCallback(),
2366 #else
2367         false,
2368         false,
2369 #endif
2370         shouldIncludeLocalhostInResourceLoadStatistics,
2371         enableResourceLoadStatisticsDebugMode,
2372 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2373         thirdPartyCookieBlockingMode(),
2374         WebCore::SameSiteStrictEnforcementEnabled::No,
2375 #endif
2376         firstPartyWebsiteDataRemovalMode,
2377         WTFMove(standaloneApplicationDomain),
2378         WTFMove(appBoundDomains),
2379         WTFMove(resourceLoadStatisticsManualPrevalentResource),
2380     };
2381
2382     NetworkSessionCreationParameters networkSessionParameters;
2383     networkSessionParameters.sessionID = m_sessionID;
2384     networkSessionParameters.boundInterfaceIdentifier = configuration().boundInterfaceIdentifier();
2385     networkSessionParameters.allowsCellularAccess = configuration().allowsCellularAccess() ? AllowsCellularAccess::Yes : AllowsCellularAccess::No;
2386     networkSessionParameters.deviceManagementRestrictionsEnabled = m_configuration->deviceManagementRestrictionsEnabled();
2387     networkSessionParameters.allLoadsBlockedByDeviceManagementRestrictionsForTesting = m_configuration->allLoadsBlockedByDeviceManagementRestrictionsForTesting();
2388     networkSessionParameters.networkCacheDirectory = WTFMove(networkCacheDirectory);
2389     networkSessionParameters.networkCacheDirectoryExtensionHandle = WTFMove(networkCacheDirectoryExtensionHandle);
2390     networkSessionParameters.hstsStorageDirectory = WTFMove(hstsStorageDirectory);
2391     networkSessionParameters.hstsStorageDirectoryExtensionHandle = WTFMove(hstsStorageDirectoryExtensionHandle);
2392     networkSessionParameters.dataConnectionServiceType = m_configuration->dataConnectionServiceType();
2393     networkSessionParameters.fastServerTrustEvaluationEnabled = m_configuration->fastServerTrustEvaluationEnabled();
2394     networkSessionParameters.networkCacheSpeculativeValidationEnabled = m_configuration->networkCacheSpeculativeValidationEnabled();
2395     networkSessionParameters.shouldUseTestingNetworkSession = m_configuration->testingSessionEnabled();
2396     networkSessionParameters.staleWhileRevalidateEnabled = m_configuration->staleWhileRevalidateEnabled();
2397     networkSessionParameters.testSpeedMultiplier = m_configuration->testSpeedMultiplier();
2398     networkSessionParameters.suppressesConnectionTerminationOnSystemChange = m_configuration->suppressesConnectionTerminationOnSystemChange();
2399     networkSessionParameters.allowsServerPreconnect = m_configuration->allowsServerPreconnect();
2400     networkSessionParameters.resourceLoadStatisticsParameters = WTFMove(resourceLoadStatisticsParameters);
2401     networkSessionParameters.requiresSecureHTTPSProxyConnection = m_configuration->requiresSecureHTTPSProxyConnection();
2402     networkSessionParameters.preventsSystemHTTPProxyAuthentication = m_configuration->preventsSystemHTTPProxyAuthentication();
2403
2404     parameters.networkSessionParameters = WTFMove(networkSessionParameters);
2405
2406 #if ENABLE(INDEXED_DATABASE)
2407     parameters.indexedDatabaseDirectory = resolvedIndexedDatabaseDirectory();
2408     if (!parameters.indexedDatabaseDirectory.isEmpty())
2409         SandboxExtension::createHandleForReadWriteDirectory(parameters.indexedDatabaseDirectory, parameters.indexedDatabaseDirectoryExtensionHandle);
2410 #endif
2411
2412 #if ENABLE(SERVICE_WORKER)
2413     parameters.serviceWorkerRegistrationDirectory = resolvedServiceWorkerRegistrationDirectory();
2414     if (!parameters.serviceWorkerRegistrationDirectory.isEmpty())
2415         SandboxExtension::createHandleForReadWriteDirectory(parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
2416     parameters.serviceWorkerProcessTerminationDelayEnabled = m_configuration->serviceWorkerProcessTerminationDelayEnabled();
2417 #endif
2418
2419     auto localStorageDirectory = resolvedLocalStorageDirectory();
2420     if (!localStorageDirectory.isEmpty()) {
2421         parameters.localStorageDirectory = localStorageDirectory;
2422         SandboxExtension::createHandleForReadWriteDirectory(localStorageDirectory, parameters.localStorageDirectoryExtensionHandle);
2423     }
2424
2425     auto cacheStorageDirectory = this->cacheStorageDirectory();
2426     if (!cacheStorageDirectory.isEmpty()) {
2427         parameters.cacheStorageDirectory = cacheStorageDirectory;
2428         SandboxExtension::createHandleForReadWriteDirectory(cacheStorageDirectory, parameters.cacheStorageDirectoryExtensionHandle);
2429     }
2430
2431     parameters.perOriginStorageQuota = perOriginStorageQuota();
2432     parameters.perThirdPartyOriginStorageQuota = perThirdPartyOriginStorageQuota();
2433
2434 #if ENABLE(RESOURCE_LOAD_STATISTICS)
2435     parameters.networkSessionParameters.resourceLoadStatisticsParameters.enabled = m_resourceLoadStatisticsEnabled;
2436 #endif
2437     platformSetNetworkParameters(parameters);
2438
2439     return parameters;
2440 }
2441
2442 #if HAVE(SEC_KEY_PROXY)
2443 void WebsiteDataStore::addSecKeyProxyStore(Ref<SecKeyProxyStore>&& store)
2444 {
2445     m_secKeyProxyStores.append(WTFMove(store));
2446 }
2447 #endif
2448
2449 #if ENABLE(WEB_AUTHN)
2450 void WebsiteDataStore::setMockWebAuthenticationConfiguration(WebCore::MockWebAuthenticationConfiguration&& configuration)
2451 {
2452     if (!m_authenticatorManager->isMock()) {
2453         m_authenticatorManager = makeUniqueRef<MockAuthenticatorManager>(WTFMove(configuration));
2454         return;
2455     }
2456     static_cast<MockAuthenticatorManager*>(&m_authenticatorManager)->setTestConfiguration(WTFMove(configuration));
2457 }
2458 #endif
2459
2460 API::HTTPCookieStore& WebsiteDataStore::cookieStore()
2461 {
2462     if (!m_cookieStore)
2463         m_cookieStore = API::HTTPCookieStore::create(*this);
2464
2465     return *m_cookieStore;
2466 }
2467
2468 void WebsiteDataStore::didCreateNetworkProcess()
2469 {
2470 }
2471
2472 void WebsiteDataStore::getLocalStorageDetails(Function<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&& completionHandler)
2473 {
2474     if (!isPersistent()) {
2475         completionHandler({ });
2476         return;
2477     }
2478
2479     for (auto& processPool : ensureProcessPools()) {
2480         processPool->ensureNetworkProcess(this).getLocalStorageDetails(m_sessionID, [completionHandler = WTFMove(completionHandler)](auto&& details) {
2481             completionHandler(WTFMove(details));
2482         });
2483         // FIXME: Support fetching from multiple pools.
2484         break;
2485     }
2486     ASSERT(!completionHandler);
2487 }
2488
2489 void WebsiteDataStore::resetQuota(CompletionHandler<void()>&& completionHandler)
2490 {
2491     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2492     for (auto& processPool : processPools()) {
2493         if (auto* process = processPool->networkProcess())
2494             process->resetQuota(m_sessionID, [callbackAggregator] { });
2495     }
2496 }
2497
2498 #if !PLATFORM(COCOA)
2499 WTF::String WebsiteDataStore::defaultMediaCacheDirectory()
2500 {
2501     // FIXME: Implement. https://bugs.webkit.org/show_bug.cgi?id=156369 and https://bugs.webkit.org/show_bug.cgi?id=156370
2502     return WTF::String();
2503 }
2504
2505 WTF::String WebsiteDataStore::defaultAlternativeServicesDirectory()
2506 {
2507     // FIXME: Implement.
2508     return WTF::String();
2509 }
2510
2511 WTF::String WebsiteDataStore::defaultJavaScriptConfigurationDirectory()
2512 {
2513     // FIXME: Implement.
2514     return WTF::String();
2515 }
2516
2517 bool WebsiteDataStore::http3Enabled()
2518 {
2519     return false;
2520 }
2521 #endif
2522
2523 #if !USE(GLIB)
2524 WTF::String WebsiteDataStore::defaultDeviceIdHashSaltsStorageDirectory()
2525 {
2526     // Not implemented.
2527     return WTF::String();
2528 }
2529 #endif
2530
2531 void WebsiteDataStore::renameOriginInWebsiteData(URL&& oldName, URL&& newName, OptionSet<WebsiteDataType> dataTypes, CompletionHandler<void()>&& completionHandler)
2532 {
2533     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2534     for (auto& processPool : WebProcessPool::allProcessPools()) {
2535         if (auto* networkProcess = processPool->networkProcess()) {
2536             networkProcess->addSession(*this);
2537             networkProcess->renameOriginInWebsiteData(m_sessionID, oldName, newName, dataTypes, [callbackAggregator] { });
2538         }
2539     }
2540 }
2541
2542 #if ENABLE(APP_BOUND_DOMAINS)
2543 void WebsiteDataStore::hasAppBoundSession(CompletionHandler<void(bool)>&& completionHandler) const
2544 {
2545     for (auto& processPool : processPools()) {
2546         if (auto* networkProcess = processPool->networkProcess()) {
2547             networkProcess->hasAppBoundSession(m_sessionID, WTFMove(completionHandler));
2548             return;
2549         }
2550     }
2551     completionHandler(false);
2552 }
2553
2554 void WebsiteDataStore::clearAppBoundSession(CompletionHandler<void()>&& completionHandler)
2555 {
2556     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2557
2558     for (auto& processPool : processPools()) {
2559         if (auto* networkProcess = processPool->networkProcess())
2560             networkProcess->clearAppBoundSession(m_sessionID, [processPool, callbackAggregator] { });
2561     }
2562 }
2563
2564 void WebsiteDataStore::forwardAppBoundDomainsToITPIfInitialized(CompletionHandler<void()>&& completionHandler)
2565 {
2566     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2567     auto appBoundDomains = appBoundDomainsIfInitialized();
2568     if (!appBoundDomains)
2569         return;
2570
2571     auto propagateAppBoundDomains = [callbackAggregator] (WebsiteDataStore* store, const HashSet<WebCore::RegistrableDomain>& domains) {
2572         if (!store)
2573             return;
2574
2575         if (store->thirdPartyCookieBlockingMode() != WebCore::ThirdPartyCookieBlockingMode::AllExceptBetweenAppBoundDomains)
2576             store->setThirdPartyCookieBlockingMode(WebCore::ThirdPartyCookieBlockingMode::AllExceptBetweenAppBoundDomains, [callbackAggregator] { });
2577
2578         store->setAppBoundDomainsForITP(domains, [callbackAggregator] { });
2579     };
2580
2581     propagateAppBoundDomains(globalDefaultDataStore().get(), *appBoundDomains);
2582
2583     for (auto* store : nonDefaultDataStores().values())
2584         propagateAppBoundDomains(store, *appBoundDomains);
2585 }
2586
2587 void WebsiteDataStore::setAppBoundDomainsForITP(const HashSet<WebCore::RegistrableDomain>& domains, CompletionHandler<void()>&& completionHandler)
2588 {
2589     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2590
2591     for (auto& processPool : processPools()) {
2592         if (auto* networkProcess = processPool->networkProcess())
2593             networkProcess->setAppBoundDomainsForResourceLoadStatistics(m_sessionID, domains, [callbackAggregator] { });
2594     }
2595 }
2596 #endif
2597
2598 void WebsiteDataStore::updateBundleIdentifierInNetworkProcess(const String& bundleIdentifier, CompletionHandler<void()>&& completionHandler)
2599 {
2600     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2601
2602     for (auto& processPool : processPools())
2603         processPool->ensureNetworkProcess().updateBundleIdentifier(bundleIdentifier, [callbackAggregator] { });
2604 }
2605
2606 void WebsiteDataStore::clearBundleIdentifierInNetworkProcess(CompletionHandler<void()>&& completionHandler)
2607 {
2608     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
2609
2610     for (auto& processPool : processPools())
2611         processPool->ensureNetworkProcess().clearBundleIdentifier([callbackAggregator] { });
2612 }
2613
2614 }