Updated resource load statistics are never merged into the SQLite Database backend...
[WebKit-https.git] / Source / WebKit / UIProcess / Network / NetworkProcessProxy.cpp
1 /*
2  * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "NetworkProcessProxy.h"
28
29 #include "APIContentRuleList.h"
30 #include "AuthenticationChallengeProxy.h"
31 #include "DownloadProxyMap.h"
32 #include "DownloadProxyMessages.h"
33 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
34 #include "LegacyCustomProtocolManagerMessages.h"
35 #include "LegacyCustomProtocolManagerProxyMessages.h"
36 #endif
37 #include "Logging.h"
38 #include "NetworkContentRuleListManagerMessages.h"
39 #include "NetworkProcessCreationParameters.h"
40 #include "NetworkProcessMessages.h"
41 #include "SandboxExtension.h"
42 #if HAVE(SEC_KEY_PROXY)
43 #include "SecKeyProxyStore.h"
44 #endif
45 #include "ShouldGrandfatherStatistics.h"
46 #include "StorageAccessStatus.h"
47 #include "WebCompiledContentRuleList.h"
48 #include "WebPageMessages.h"
49 #include "WebPageProxy.h"
50 #include "WebProcessMessages.h"
51 #include "WebProcessPool.h"
52 #include "WebProcessProxy.h"
53 #include "WebResourceLoadStatisticsStore.h"
54 #include "WebUserContentControllerProxy.h"
55 #include "WebsiteData.h"
56 #include "WebsiteDataStoreClient.h"
57 #include <WebCore/ClientOrigin.h>
58 #include <WebCore/RegistrableDomain.h>
59 #include <wtf/CompletionHandler.h>
60
61 #if ENABLE(SEC_ITEM_SHIM)
62 #include "SecItemShimProxy.h"
63 #endif
64
65 #if PLATFORM(IOS_FAMILY)
66 #include <wtf/spi/darwin/XPCSPI.h>
67 #endif
68
69 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, connection())
70
71 namespace WebKit {
72 using namespace WebCore;
73
74 static uint64_t generateCallbackID()
75 {
76     static uint64_t callbackID;
77
78     return ++callbackID;
79 }
80
81 NetworkProcessProxy::NetworkProcessProxy(WebProcessPool& processPool)
82     : AuxiliaryProcessProxy(processPool.alwaysRunsAtBackgroundPriority())
83     , m_processPool(processPool)
84 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
85     , m_customProtocolManagerProxy(*this)
86 #endif
87     , m_throttler(*this, processPool.shouldTakeUIBackgroundAssertion())
88 {
89     connect();
90
91     if (auto* websiteDataStore = m_processPool.websiteDataStore())
92         m_websiteDataStores.set(websiteDataStore->sessionID(), makeRef(*websiteDataStore));
93 }
94
95 NetworkProcessProxy::~NetworkProcessProxy()
96 {
97     ASSERT(m_pendingFetchWebsiteDataCallbacks.isEmpty());
98     ASSERT(m_pendingDeleteWebsiteDataCallbacks.isEmpty());
99     ASSERT(m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty());
100 #if ENABLE(CONTENT_EXTENSIONS)
101     for (auto* proxy : m_webUserContentControllerProxies)
102         proxy->removeNetworkProcess(*this);
103 #endif
104
105     if (m_downloadProxyMap)
106         m_downloadProxyMap->invalidate();
107
108     for (auto& request : m_connectionRequests.values())
109         request.reply({ });
110 }
111
112 void NetworkProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions)
113 {
114     launchOptions.processType = ProcessLauncher::ProcessType::Network;
115     AuxiliaryProcessProxy::getLaunchOptions(launchOptions);
116
117     if (processPool().shouldMakeNextNetworkProcessLaunchFailForTesting()) {
118         processPool().setShouldMakeNextNetworkProcessLaunchFailForTesting(false);
119         launchOptions.shouldMakeProcessLaunchFailForTesting = true;
120     }
121 }
122
123 void NetworkProcessProxy::connectionWillOpen(IPC::Connection& connection)
124 {
125 #if ENABLE(SEC_ITEM_SHIM)
126     SecItemShimProxy::singleton().initializeConnection(connection);
127 #else
128     UNUSED_PARAM(connection);
129 #endif
130 }
131
132 void NetworkProcessProxy::processWillShutDown(IPC::Connection& connection)
133 {
134     ASSERT_UNUSED(connection, this->connection() == &connection);
135 }
136
137 void NetworkProcessProxy::getNetworkProcessConnection(WebProcessProxy& webProcessProxy, Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply&& reply)
138 {
139     m_connectionRequests.add(++m_connectionRequestIdentifier, ConnectionRequest { makeWeakPtr(webProcessProxy), WTFMove(reply) });
140     if (state() == State::Launching)
141         return;
142     openNetworkProcessConnection(m_connectionRequestIdentifier, webProcessProxy);
143 }
144
145 void NetworkProcessProxy::openNetworkProcessConnection(uint64_t connectionRequestIdentifier, WebProcessProxy& webProcessProxy)
146 {
147     connection()->sendWithAsyncReply(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess { webProcessProxy.coreProcessIdentifier(), webProcessProxy.sessionID() }, [this, weakThis = makeWeakPtr(this), webProcessProxy = makeWeakPtr(webProcessProxy), connectionRequestIdentifier](auto&& connectionIdentifier) mutable {
148         if (!weakThis)
149             return;
150
151         if (!connectionIdentifier) {
152             // Network process probably crashed, the connection request should have been moved.
153             ASSERT(m_connectionRequests.isEmpty());
154             return;
155         }
156
157         ASSERT(m_connectionRequests.contains(connectionRequestIdentifier));
158         auto request = m_connectionRequests.take(connectionRequestIdentifier);
159
160 #if USE(UNIX_DOMAIN_SOCKETS) || OS(WINDOWS)
161         request.reply(*connectionIdentifier);
162 #elif OS(DARWIN)
163         MESSAGE_CHECK(MACH_PORT_VALID(connectionIdentifier->port()));
164         request.reply(IPC::Attachment { connectionIdentifier->port(), MACH_MSG_TYPE_MOVE_SEND });
165 #else
166         notImplemented();
167 #endif
168     }, 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
169 }
170
171 void NetworkProcessProxy::synthesizeAppIsBackground(bool background)
172 {
173     if (m_downloadProxyMap) {
174         if (background)
175             m_downloadProxyMap->applicationDidEnterBackground();
176         else
177             m_downloadProxyMap->applicationWillEnterForeground();
178     }
179 }
180
181 DownloadProxy& NetworkProcessProxy::createDownloadProxy(WebsiteDataStore& dataStore, const ResourceRequest& resourceRequest)
182 {
183     if (!m_downloadProxyMap)
184         m_downloadProxyMap = makeUnique<DownloadProxyMap>(*this);
185
186     return m_downloadProxyMap->createDownloadProxy(dataStore, m_processPool, resourceRequest);
187 }
188
189 void NetworkProcessProxy::fetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, CompletionHandler<void (WebsiteData)>&& completionHandler)
190 {
191     ASSERT(canSendMessage());
192
193     uint64_t callbackID = generateCallbackID();
194     RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is fetching Website data", this);
195
196     m_pendingFetchWebsiteDataCallbacks.add(callbackID, [this, token = throttler().backgroundActivityToken(), completionHandler = WTFMove(completionHandler), sessionID] (WebsiteData websiteData) mutable {
197 #if RELEASE_LOG_DISABLED
198         UNUSED_PARAM(this);
199         UNUSED_PARAM(sessionID);
200 #endif
201         completionHandler(WTFMove(websiteData));
202         RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done fetching Website data", this);
203     });
204
205     send(Messages::NetworkProcess::FetchWebsiteData(sessionID, dataTypes, fetchOptions, callbackID), 0);
206 }
207
208 void NetworkProcessProxy::deleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, WallTime modifiedSince, CompletionHandler<void ()>&& completionHandler)
209 {
210     auto callbackID = generateCallbackID();
211     RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is deleting Website data", this);
212
213     m_pendingDeleteWebsiteDataCallbacks.add(callbackID, [this, token = throttler().backgroundActivityToken(), completionHandler = WTFMove(completionHandler), sessionID] () mutable {
214 #if RELEASE_LOG_DISABLED
215         UNUSED_PARAM(this);
216         UNUSED_PARAM(sessionID);
217 #endif
218         completionHandler();
219         RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done deleting Website data", this);
220     });
221     send(Messages::NetworkProcess::DeleteWebsiteData(sessionID, dataTypes, modifiedSince, callbackID), 0);
222 }
223
224 void NetworkProcessProxy::deleteWebsiteDataForOrigins(PAL::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, const Vector<WebCore::SecurityOriginData>& origins, const Vector<String>& cookieHostNames, const Vector<String>& HSTSCacheHostNames, CompletionHandler<void()>&& completionHandler)
225 {
226     ASSERT(canSendMessage());
227
228     uint64_t callbackID = generateCallbackID();
229     RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is deleting Website data for several origins", this);
230
231     m_pendingDeleteWebsiteDataForOriginsCallbacks.add(callbackID, [this, token = throttler().backgroundActivityToken(), completionHandler = WTFMove(completionHandler), sessionID] () mutable {
232 #if RELEASE_LOG_DISABLED
233         UNUSED_PARAM(this);
234         UNUSED_PARAM(sessionID);
235 #endif
236         completionHandler();
237         RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done deleting Website data for several origins", this);
238     });
239
240     send(Messages::NetworkProcess::DeleteWebsiteDataForOrigins(sessionID, dataTypes, origins, cookieHostNames, HSTSCacheHostNames, callbackID), 0);
241 }
242
243 void NetworkProcessProxy::networkProcessCrashed()
244 {
245     clearCallbackStates();
246
247     Vector<std::pair<RefPtr<WebProcessProxy>, Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>> pendingRequests;
248     pendingRequests.reserveInitialCapacity(m_connectionRequests.size());
249     for (auto& request : m_connectionRequests.values()) {
250         if (request.webProcess)
251             pendingRequests.uncheckedAppend(std::make_pair(makeRefPtr(request.webProcess.get()), WTFMove(request.reply)));
252         else
253             request.reply({ });
254     }
255     m_connectionRequests.clear();
256
257     // Tell the network process manager to forget about this network process proxy. This will cause us to be deleted.
258     m_processPool.networkProcessCrashed(*this, WTFMove(pendingRequests));
259 }
260
261 void NetworkProcessProxy::clearCallbackStates()
262 {
263     while (!m_pendingFetchWebsiteDataCallbacks.isEmpty())
264         m_pendingFetchWebsiteDataCallbacks.take(m_pendingFetchWebsiteDataCallbacks.begin()->key)(WebsiteData { });
265
266     while (!m_pendingDeleteWebsiteDataCallbacks.isEmpty())
267         m_pendingDeleteWebsiteDataCallbacks.take(m_pendingDeleteWebsiteDataCallbacks.begin()->key)();
268
269     while (!m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty())
270         m_pendingDeleteWebsiteDataForOriginsCallbacks.take(m_pendingDeleteWebsiteDataForOriginsCallbacks.begin()->key)();
271 }
272
273 void NetworkProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
274 {
275     if (dispatchMessage(connection, decoder))
276         return;
277
278     if (m_processPool.dispatchMessage(connection, decoder))
279         return;
280
281     didReceiveNetworkProcessProxyMessage(connection, decoder);
282 }
283
284 void NetworkProcessProxy::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
285 {
286     if (dispatchSyncMessage(connection, decoder, replyEncoder))
287         return;
288
289     didReceiveSyncNetworkProcessProxyMessage(connection, decoder, replyEncoder);
290 }
291
292 void NetworkProcessProxy::didClose(IPC::Connection&)
293 {
294     auto protectedProcessPool = makeRef(m_processPool);
295
296     if (m_downloadProxyMap)
297         m_downloadProxyMap->invalidate();
298 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
299     m_customProtocolManagerProxy.invalidate();
300 #endif
301
302     m_tokenForHoldingLockedFiles = nullptr;
303     
304     m_syncAllCookiesToken = nullptr;
305     m_syncAllCookiesCounter = 0;
306
307     // This will cause us to be deleted.
308     networkProcessCrashed();
309 }
310
311 void NetworkProcessProxy::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
312 {
313 }
314
315 void NetworkProcessProxy::processAuthenticationChallenge(PAL::SessionID sessionID, Ref<AuthenticationChallengeProxy>&& authenticationChallenge)
316 {
317     auto* store = websiteDataStoreFromSessionID(sessionID);
318     if (!store || authenticationChallenge->core().protectionSpace().authenticationScheme() != ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested) {
319         authenticationChallenge->listener().completeChallenge(AuthenticationChallengeDisposition::PerformDefaultHandling);
320         return;
321     }
322     store->client().didReceiveAuthenticationChallenge(WTFMove(authenticationChallenge));
323 }
324
325 void NetworkProcessProxy::didReceiveAuthenticationChallenge(PAL::SessionID sessionID, WebPageProxyIdentifier pageID, const Optional<SecurityOriginData>& topOrigin, WebCore::AuthenticationChallenge&& coreChallenge, uint64_t challengeID)
326 {
327 #if HAVE(SEC_KEY_PROXY)
328     WeakPtr<SecKeyProxyStore> secKeyProxyStore;
329     if (coreChallenge.protectionSpace().authenticationScheme() == ProtectionSpaceAuthenticationSchemeClientCertificateRequested) {
330         if (auto* store = websiteDataStoreFromSessionID(sessionID)) {
331             auto newSecKeyProxyStore = SecKeyProxyStore::create();
332             secKeyProxyStore = makeWeakPtr(newSecKeyProxyStore.get());
333             store->addSecKeyProxyStore(WTFMove(newSecKeyProxyStore));
334         }
335     }
336     auto authenticationChallenge = AuthenticationChallengeProxy::create(WTFMove(coreChallenge), challengeID, makeRef(*connection()), WTFMove(secKeyProxyStore));
337 #else
338     auto authenticationChallenge = AuthenticationChallengeProxy::create(WTFMove(coreChallenge), challengeID, makeRef(*connection()), nullptr);
339 #endif
340
341     WebPageProxy* page = nullptr;
342     if (pageID)
343         page = WebProcessProxy::webPage(pageID);
344
345     if (page) {
346         page->didReceiveAuthenticationChallengeProxy(WTFMove(authenticationChallenge));
347         return;
348     }
349
350     if (!topOrigin || !m_processPool.isServiceWorkerPageID(pageID)) {
351         processAuthenticationChallenge(sessionID, WTFMove(authenticationChallenge));
352         return;
353     }
354
355     WebPageProxy::forMostVisibleWebPageIfAny(sessionID, *topOrigin, [this, weakThis = makeWeakPtr(this), sessionID, authenticationChallenge = WTFMove(authenticationChallenge)](auto* page) mutable {
356         if (!weakThis)
357             return;
358
359         if (page) {
360             page->didReceiveAuthenticationChallengeProxy(WTFMove(authenticationChallenge));
361             return;
362         }
363         processAuthenticationChallenge(sessionID, WTFMove(authenticationChallenge));
364     });
365 }
366
367 void NetworkProcessProxy::didFetchWebsiteData(uint64_t callbackID, const WebsiteData& websiteData)
368 {
369     auto callback = m_pendingFetchWebsiteDataCallbacks.take(callbackID);
370     callback(websiteData);
371 }
372
373 void NetworkProcessProxy::didDeleteWebsiteData(uint64_t callbackID)
374 {
375     auto callback = m_pendingDeleteWebsiteDataCallbacks.take(callbackID);
376     callback();
377 }
378
379 void NetworkProcessProxy::didDeleteWebsiteDataForOrigins(uint64_t callbackID)
380 {
381     auto callback = m_pendingDeleteWebsiteDataForOriginsCallbacks.take(callbackID);
382     callback();
383 }
384
385 void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier)
386 {
387     AuxiliaryProcessProxy::didFinishLaunching(launcher, connectionIdentifier);
388
389     if (!IPC::Connection::identifierIsValid(connectionIdentifier)) {
390         networkProcessCrashed();
391         return;
392     }
393
394     auto connectionRequests = WTFMove(m_connectionRequests);
395     for (auto& connectionRequest : connectionRequests.values()) {
396         if (connectionRequest.webProcess)
397             getNetworkProcessConnection(*connectionRequest.webProcess, WTFMove(connectionRequest.reply));
398         else
399             connectionRequest.reply({ });
400     }
401
402 #if PLATFORM(COCOA)
403     if (m_processPool.processSuppressionEnabled())
404         setProcessSuppressionEnabled(true);
405 #endif
406     
407 #if PLATFORM(IOS_FAMILY)
408     if (xpc_connection_t connection = this->connection()->xpcConnection())
409         m_throttler.didConnectToProcess(xpc_connection_get_pid(connection));
410 #endif
411 }
412
413 void NetworkProcessProxy::logDiagnosticMessage(WebPageProxyIdentifier pageID, const String& message, const String& description, WebCore::ShouldSample shouldSample)
414 {
415     WebPageProxy* page = WebProcessProxy::webPage(pageID);
416     // FIXME: We do this null-check because by the time the decision to log is made, the page may be gone. We should refactor to avoid this,
417     // but for now we simply drop the message in the rare case this happens.
418     if (!page)
419         return;
420
421     page->logDiagnosticMessage(message, description, shouldSample);
422 }
423
424 void NetworkProcessProxy::logDiagnosticMessageWithResult(WebPageProxyIdentifier pageID, const String& message, const String& description, uint32_t result, WebCore::ShouldSample shouldSample)
425 {
426     WebPageProxy* page = WebProcessProxy::webPage(pageID);
427     // FIXME: We do this null-check because by the time the decision to log is made, the page may be gone. We should refactor to avoid this,
428     // but for now we simply drop the message in the rare case this happens.
429     if (!page)
430         return;
431
432     page->logDiagnosticMessageWithResult(message, description, result, shouldSample);
433 }
434
435 void NetworkProcessProxy::logDiagnosticMessageWithValue(WebPageProxyIdentifier pageID, const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample shouldSample)
436 {
437     WebPageProxy* page = WebProcessProxy::webPage(pageID);
438     // FIXME: We do this null-check because by the time the decision to log is made, the page may be gone. We should refactor to avoid this,
439     // but for now we simply drop the message in the rare case this happens.
440     if (!page)
441         return;
442
443     page->logDiagnosticMessageWithValue(message, description, value, significantFigures, shouldSample);
444 }
445
446 void NetworkProcessProxy::logGlobalDiagnosticMessageWithValue(const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample shouldSample)
447 {
448     if (auto* page = WebPageProxy::nonEphemeralWebPageProxy())
449         page->logDiagnosticMessageWithValue(message, description, value, significantFigures, shouldSample);
450 }
451
452 #if ENABLE(RESOURCE_LOAD_STATISTICS)
453 void NetworkProcessProxy::dumpResourceLoadStatistics(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
454 {
455     if (!canSendMessage()) {
456         completionHandler({ });
457         return;
458     }
459     
460     sendWithAsyncReply(Messages::NetworkProcess::DumpResourceLoadStatistics(sessionID), WTFMove(completionHandler));
461 }
462
463 void NetworkProcessProxy::updatePrevalentDomainsToBlockCookiesFor(PAL::SessionID sessionID, const Vector<RegistrableDomain>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
464 {
465     if (!canSendMessage()) {
466         completionHandler();
467         return;
468     }
469
470     Vector<RegistrableDomain> registrableDomainsToBlock;
471     registrableDomainsToBlock.reserveInitialCapacity(domainsToBlock.size());
472     for (auto& domain : domainsToBlock)
473         registrableDomainsToBlock.uncheckedAppend(domain);
474
475     sendWithAsyncReply(Messages::NetworkProcess::UpdatePrevalentDomainsToBlockCookiesFor(sessionID, registrableDomainsToBlock), WTFMove(completionHandler));
476 }
477
478 void NetworkProcessProxy::isPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
479 {
480     if (!canSendMessage()) {
481         completionHandler(false);
482         return;
483     }
484
485     sendWithAsyncReply(Messages::NetworkProcess::IsPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
486 }
487
488 void NetworkProcessProxy::isVeryPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
489 {
490     if (!canSendMessage()) {
491         completionHandler(false);
492         return;
493     }
494
495     sendWithAsyncReply(Messages::NetworkProcess::IsVeryPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
496 }
497
498 void NetworkProcessProxy::setPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void()>&& completionHandler)
499 {
500     if (!canSendMessage()) {
501         completionHandler();
502         return;
503     }
504
505     sendWithAsyncReply(Messages::NetworkProcess::SetPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
506 }
507
508 void NetworkProcessProxy::setPrevalentResourceForDebugMode(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void()>&& completionHandler)
509 {
510     if (!canSendMessage()) {
511         completionHandler();
512         return;
513     }
514
515     sendWithAsyncReply(Messages::NetworkProcess::SetPrevalentResourceForDebugMode(sessionID, resourceDomain), WTFMove(completionHandler));
516 }
517
518 void NetworkProcessProxy::setVeryPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void()>&& completionHandler)
519 {
520     if (!canSendMessage()) {
521         completionHandler();
522         return;
523     }
524
525     sendWithAsyncReply(Messages::NetworkProcess::SetVeryPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
526 }
527
528 void NetworkProcessProxy::setLastSeen(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, Seconds lastSeen, CompletionHandler<void()>&& completionHandler)
529 {
530     if (!canSendMessage()) {
531         completionHandler();
532         return;
533     }
534     
535     sendWithAsyncReply(Messages::NetworkProcess::SetLastSeen(sessionID, resourceDomain, lastSeen), WTFMove(completionHandler));
536 }
537
538 void NetworkProcessProxy::mergeStatisticForTesting(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, const RegistrableDomain& topFrameDomain, Seconds lastSeen, bool hadUserInteraction, Seconds mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, unsigned dataRecordsRemoved, CompletionHandler<void()>&& completionHandler)
539 {
540     sendWithAsyncReply(Messages::NetworkProcess::MergeStatisticForTesting(sessionID, resourceDomain, topFrameDomain, lastSeen, hadUserInteraction, mostRecentUserInteraction, isGrandfathered, isPrevalent, isVeryPrevalent, dataRecordsRemoved), WTFMove(completionHandler));
541 }
542
543 void NetworkProcessProxy::clearPrevalentResource(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void()>&& completionHandler)
544 {
545     if (!canSendMessage()) {
546         completionHandler();
547         return;
548     }
549     
550     sendWithAsyncReply(Messages::NetworkProcess::ClearPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
551 }
552     
553 void NetworkProcessProxy::scheduleCookieBlockingUpdate(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
554 {
555     if (!canSendMessage()) {
556         completionHandler();
557         return;
558     }
559     
560     sendWithAsyncReply(Messages::NetworkProcess::ScheduleCookieBlockingUpdate(sessionID), WTFMove(completionHandler));
561 }
562
563 void NetworkProcessProxy::scheduleClearInMemoryAndPersistent(PAL::SessionID sessionID, Optional<WallTime> modifiedSince, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
564 {
565     if (!canSendMessage()) {
566         completionHandler();
567         return;
568     }
569
570     sendWithAsyncReply(Messages::NetworkProcess::ScheduleClearInMemoryAndPersistent(sessionID, modifiedSince, shouldGrandfather), WTFMove(completionHandler));
571 }
572
573 void NetworkProcessProxy::scheduleStatisticsAndDataRecordsProcessing(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
574 {
575     if (!canSendMessage()) {
576         completionHandler();
577         return;
578     }
579     
580     sendWithAsyncReply(Messages::NetworkProcess::ScheduleStatisticsAndDataRecordsProcessing(sessionID), WTFMove(completionHandler));
581 }
582
583 void NetworkProcessProxy::logUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void()>&& completionHandler)
584 {
585     if (!canSendMessage()) {
586         completionHandler();
587         return;
588     }
589
590     sendWithAsyncReply(Messages::NetworkProcess::LogUserInteraction(sessionID, resourceDomain), WTFMove(completionHandler));
591 }
592
593 void NetworkProcessProxy::hasHadUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
594 {
595     if (!canSendMessage()) {
596         completionHandler(false);
597         return;
598     }
599     
600     sendWithAsyncReply(Messages::NetworkProcess::HadUserInteraction(sessionID, resourceDomain), WTFMove(completionHandler));
601 }
602
603 void NetworkProcessProxy::clearUserInteraction(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void()>&& completionHandler)
604 {
605     if (!canSendMessage()) {
606         completionHandler();
607         return;
608     }
609     
610     sendWithAsyncReply(Messages::NetworkProcess::ClearUserInteraction(sessionID, resourceDomain), WTFMove(completionHandler));
611 }
612
613 void NetworkProcessProxy::hasLocalStorage(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
614 {
615     if (!canSendMessage()) {
616         completionHandler(false);
617         return;
618     }
619
620     sendWithAsyncReply(Messages::NetworkProcess::HasLocalStorage(sessionID, resourceDomain), WTFMove(completionHandler));
621 }
622
623 void NetworkProcessProxy::setAgeCapForClientSideCookies(PAL::SessionID sessionID, Optional<Seconds> seconds, CompletionHandler<void()>&& completionHandler)
624 {
625     if (!canSendMessage()) {
626         completionHandler();
627         return;
628     }
629     
630     sendWithAsyncReply(Messages::NetworkProcess::SetAgeCapForClientSideCookies(sessionID, seconds), WTFMove(completionHandler));
631 }
632
633 void NetworkProcessProxy::setTimeToLiveUserInteraction(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
634 {
635     if (!canSendMessage()) {
636         completionHandler();
637         return;
638     }
639     
640     sendWithAsyncReply(Messages::NetworkProcess::SetTimeToLiveUserInteraction(sessionID, seconds), WTFMove(completionHandler));
641 }
642
643 void NetworkProcessProxy::setNotifyPagesWhenTelemetryWasCaptured(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
644 {
645     if (!canSendMessage()) {
646         completionHandler();
647         return;
648     }
649     
650     sendWithAsyncReply(Messages::NetworkProcess::SetNotifyPagesWhenTelemetryWasCaptured(sessionID, value), WTFMove(completionHandler));
651 }
652
653 void NetworkProcessProxy::setNotifyPagesWhenDataRecordsWereScanned(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
654 {
655     if (!canSendMessage()) {
656         completionHandler();
657         return;
658     }
659     
660     sendWithAsyncReply(Messages::NetworkProcess::SetNotifyPagesWhenDataRecordsWereScanned(sessionID, value), WTFMove(completionHandler));
661 }
662
663 void NetworkProcessProxy::setIsRunningResourceLoadStatisticsTest(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
664 {
665     if (!canSendMessage()) {
666         completionHandler();
667         return;
668     }
669     
670     sendWithAsyncReply(Messages::NetworkProcess::SetIsRunningResourceLoadStatisticsTest(sessionID, value), WTFMove(completionHandler));
671 }
672
673 void NetworkProcessProxy::setSubframeUnderTopFrameDomain(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void()>&& completionHandler)
674 {
675     if (!canSendMessage()) {
676         completionHandler();
677         return;
678     }
679     
680     sendWithAsyncReply(Messages::NetworkProcess::SetSubframeUnderTopFrameDomain(sessionID, subFrameDomain, topFrameDomain), WTFMove(completionHandler));
681 }
682
683 void NetworkProcessProxy::isRegisteredAsRedirectingTo(PAL::SessionID sessionID, const RegistrableDomain& domainRedirectedFrom, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void(bool)>&& completionHandler)
684 {
685     if (!canSendMessage()) {
686         completionHandler(false);
687         return;
688     }
689     
690     sendWithAsyncReply(Messages::NetworkProcess::IsRegisteredAsRedirectingTo(sessionID, domainRedirectedFrom, domainRedirectedTo), WTFMove(completionHandler));
691 }
692
693 void NetworkProcessProxy::isRegisteredAsSubFrameUnder(PAL::SessionID sessionID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void(bool)>&& completionHandler)
694 {
695     if (!canSendMessage()) {
696         completionHandler(false);
697         return;
698     }
699     
700     sendWithAsyncReply(Messages::NetworkProcess::IsRegisteredAsSubFrameUnder(sessionID, subFrameDomain, topFrameDomain), WTFMove(completionHandler));
701 }
702
703 void NetworkProcessProxy::setSubresourceUnderTopFrameDomain(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void()>&& completionHandler)
704 {
705     if (!canSendMessage()) {
706         completionHandler();
707         return;
708     }
709     
710     sendWithAsyncReply(Messages::NetworkProcess::SetSubresourceUnderTopFrameDomain(sessionID, subresourceDomain, topFrameDomain), WTFMove(completionHandler));
711 }
712
713 void NetworkProcessProxy::isRegisteredAsSubresourceUnder(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void(bool)>&& completionHandler)
714 {
715     if (!canSendMessage()) {
716         completionHandler(false);
717         return;
718     }
719     
720     sendWithAsyncReply(Messages::NetworkProcess::IsRegisteredAsSubresourceUnder(sessionID, subresourceDomain, topFrameDomain), WTFMove(completionHandler));
721 }
722
723 void NetworkProcessProxy::setSubresourceUniqueRedirectTo(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void()>&& completionHandler)
724 {
725     if (!canSendMessage()) {
726         completionHandler();
727         return;
728     }
729     
730     sendWithAsyncReply(Messages::NetworkProcess::SetSubresourceUniqueRedirectTo(sessionID, subresourceDomain, domainRedirectedTo), WTFMove(completionHandler));
731 }
732
733 void NetworkProcessProxy::setSubresourceUniqueRedirectFrom(PAL::SessionID sessionID, const RegistrableDomain& subresourceDomain, const RegistrableDomain& domainRedirectedFrom, CompletionHandler<void()>&& completionHandler)
734 {
735     if (!canSendMessage()) {
736         completionHandler();
737         return;
738     }
739     
740     sendWithAsyncReply(Messages::NetworkProcess::SetSubresourceUniqueRedirectFrom(sessionID, subresourceDomain, domainRedirectedFrom), WTFMove(completionHandler));
741 }
742
743 void NetworkProcessProxy::setTopFrameUniqueRedirectTo(PAL::SessionID sessionID, const RegistrableDomain& topFrameDomain, const RegistrableDomain& domainRedirectedTo, CompletionHandler<void()>&& completionHandler)
744 {
745     if (!canSendMessage()) {
746         completionHandler();
747         return;
748     }
749     
750     sendWithAsyncReply(Messages::NetworkProcess::SetTopFrameUniqueRedirectTo(sessionID, topFrameDomain, domainRedirectedTo), WTFMove(completionHandler));
751 }
752
753 void NetworkProcessProxy::setTopFrameUniqueRedirectFrom(PAL::SessionID sessionID, const RegistrableDomain& topFrameDomain, const RegistrableDomain& domainRedirectedFrom, CompletionHandler<void()>&& completionHandler)
754 {
755     if (!canSendMessage()) {
756         completionHandler();
757         return;
758     }
759     
760     sendWithAsyncReply(Messages::NetworkProcess::SetTopFrameUniqueRedirectFrom(sessionID, topFrameDomain, domainRedirectedFrom), WTFMove(completionHandler));
761 }
762
763 void NetworkProcessProxy::isGrandfathered(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
764 {
765     if (!canSendMessage()) {
766         completionHandler(false);
767         return;
768     }
769     
770     sendWithAsyncReply(Messages::NetworkProcess::IsGrandfathered(sessionID, resourceDomain), WTFMove(completionHandler));
771 }
772
773 void NetworkProcessProxy::setGrandfathered(PAL::SessionID sessionID, const RegistrableDomain& resourceDomain, bool isGrandfathered, CompletionHandler<void()>&& completionHandler)
774 {
775     if (!canSendMessage()) {
776         completionHandler();
777         return;
778     }
779     
780     sendWithAsyncReply(Messages::NetworkProcess::SetGrandfathered(sessionID, resourceDomain, isGrandfathered), WTFMove(completionHandler));
781 }
782
783 void NetworkProcessProxy::setUseITPDatabase(PAL::SessionID sessionID, bool value)
784 {
785     if (!canSendMessage())
786         return;
787     
788     send(Messages::NetworkProcess::SetUseITPDatabase(sessionID, value), 0);
789 }
790
791 void NetworkProcessProxy::requestStorageAccessConfirm(WebPageProxyIdentifier pageID, FrameIdentifier frameID, const RegistrableDomain& subFrameDomain, const RegistrableDomain& topFrameDomain, CompletionHandler<void(bool)>&& completionHandler)
792 {
793     auto* page = WebProcessProxy::webPage(pageID);
794     if (!page) {
795         completionHandler(false);
796         return;
797     }
798     
799     page->requestStorageAccessConfirm(subFrameDomain, topFrameDomain, frameID, WTFMove(completionHandler));
800 }
801
802 void NetworkProcessProxy::getAllStorageAccessEntries(PAL::SessionID sessionID, CompletionHandler<void(Vector<String> domains)>&& completionHandler)
803 {
804     if (!canSendMessage()) {
805         completionHandler({ });
806         return;
807     }
808
809     sendWithAsyncReply(Messages::NetworkProcess::GetAllStorageAccessEntries(sessionID), WTFMove(completionHandler));
810 }
811
812 void NetworkProcessProxy::setCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
813 {
814     if (!canSendMessage()) {
815         completionHandler();
816         return;
817     }
818
819     sendWithAsyncReply(Messages::NetworkProcess::SetCacheMaxAgeCapForPrevalentResources(sessionID, seconds), WTFMove(completionHandler));
820 }
821
822 void NetworkProcessProxy::setCacheMaxAgeCap(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
823 {
824     if (!canSendMessage()) {
825         completionHandler();
826         return;
827     }
828     
829     sendWithAsyncReply(Messages::NetworkProcess::SetCacheMaxAgeCapForPrevalentResources(sessionID, seconds), WTFMove(completionHandler));
830 }
831
832 void NetworkProcessProxy::setGrandfatheringTime(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
833 {
834     if (!canSendMessage()) {
835         completionHandler();
836         return;
837     }
838     
839     sendWithAsyncReply(Messages::NetworkProcess::SetGrandfatheringTime(sessionID, seconds), WTFMove(completionHandler));
840 }
841
842 void NetworkProcessProxy::setMaxStatisticsEntries(PAL::SessionID sessionID, size_t maximumEntryCount, CompletionHandler<void()>&& completionHandler)
843 {
844     if (!canSendMessage()) {
845         completionHandler();
846         return;
847     }
848
849     sendWithAsyncReply(Messages::NetworkProcess::SetMaxStatisticsEntries(sessionID, maximumEntryCount), WTFMove(completionHandler));
850 }
851
852 void NetworkProcessProxy::setMinimumTimeBetweenDataRecordsRemoval(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
853 {
854     if (!canSendMessage()) {
855         completionHandler();
856         return;
857     }
858     
859     sendWithAsyncReply(Messages::NetworkProcess::SetMinimumTimeBetweenDataRecordsRemoval(sessionID, seconds), WTFMove(completionHandler));
860 }
861
862 void NetworkProcessProxy::setPruneEntriesDownTo(PAL::SessionID sessionID, size_t pruneTargetCount, CompletionHandler<void()>&& completionHandler)
863 {
864     if (!canSendMessage()) {
865         completionHandler();
866         return;
867     }
868
869     sendWithAsyncReply(Messages::NetworkProcess::SetPruneEntriesDownTo(sessionID, pruneTargetCount), WTFMove(completionHandler));
870 }
871
872 void NetworkProcessProxy::setShouldClassifyResourcesBeforeDataRecordsRemoval(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
873 {
874     if (!canSendMessage()) {
875         completionHandler();
876         return;
877     }
878     
879     sendWithAsyncReply(Messages::NetworkProcess::SetShouldClassifyResourcesBeforeDataRecordsRemoval(sessionID, value), WTFMove(completionHandler));
880 }
881
882 void NetworkProcessProxy::setResourceLoadStatisticsDebugMode(PAL::SessionID sessionID, bool debugMode, CompletionHandler<void()>&& completionHandler)
883 {
884     if (!canSendMessage()) {
885         completionHandler();
886         return;
887     }
888     
889     sendWithAsyncReply(Messages::NetworkProcess::SetResourceLoadStatisticsDebugMode(sessionID, debugMode), WTFMove(completionHandler));
890 }
891
892 void NetworkProcessProxy::resetCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
893 {
894     if (!canSendMessage()) {
895         completionHandler();
896         return;
897     }
898     
899     sendWithAsyncReply(Messages::NetworkProcess::ResetCacheMaxAgeCapForPrevalentResources(sessionID), WTFMove(completionHandler));
900 }
901
902 void NetworkProcessProxy::resetParametersToDefaultValues(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
903 {
904     if (!canSendMessage()) {
905         completionHandler();
906         return;
907     }
908     
909     sendWithAsyncReply(Messages::NetworkProcess::ResetParametersToDefaultValues(sessionID), WTFMove(completionHandler));
910 }
911
912 void NetworkProcessProxy::submitTelemetry(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
913 {
914     if (!canSendMessage()) {
915         completionHandler();
916         return;
917     }
918     
919     sendWithAsyncReply(Messages::NetworkProcess::SubmitTelemetry(sessionID), WTFMove(completionHandler));
920 }
921
922 void NetworkProcessProxy::scheduleClearInMemoryAndPersistent(PAL::SessionID sessionID, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
923 {
924     if (!canSendMessage()) {
925         completionHandler();
926         return;
927     }
928
929     sendWithAsyncReply(Messages::NetworkProcess::ScheduleClearInMemoryAndPersistent(sessionID, { }, shouldGrandfather), WTFMove(completionHandler));
930 }
931
932 void NetworkProcessProxy::logTestingEvent(PAL::SessionID sessionID, const String& event)
933 {
934     if (auto* websiteDataStore = websiteDataStoreFromSessionID(sessionID))
935         websiteDataStore->logTestingEvent(event);
936 }
937
938 void NetworkProcessProxy::notifyResourceLoadStatisticsProcessed()
939 {
940     WebProcessProxy::notifyPageStatisticsAndDataRecordsProcessed();
941 }
942
943 void NetworkProcessProxy::notifyWebsiteDataDeletionForRegistrableDomainsFinished()
944 {
945     WebProcessProxy::notifyWebsiteDataDeletionForRegistrableDomainsFinished();
946 }
947
948 void NetworkProcessProxy::notifyWebsiteDataScanForRegistrableDomainsFinished()
949 {
950     WebProcessProxy::notifyWebsiteDataScanForRegistrableDomainsFinished();
951 }
952
953 void NetworkProcessProxy::notifyResourceLoadStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins)
954 {
955     API::Dictionary::MapType messageBody;
956     messageBody.set("TotalPrevalentResources"_s, API::UInt64::create(totalPrevalentResources));
957     messageBody.set("TotalPrevalentResourcesWithUserInteraction"_s, API::UInt64::create(totalPrevalentResourcesWithUserInteraction));
958     messageBody.set("Top3SubframeUnderTopFrameOrigins"_s, API::UInt64::create(top3SubframeUnderTopFrameOrigins));
959
960     WebProcessProxy::notifyPageStatisticsTelemetryFinished(API::Dictionary::create(messageBody).ptr());
961 }
962
963 void NetworkProcessProxy::didCommitCrossSiteLoadWithDataTransfer(PAL::SessionID sessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, OptionSet<WebCore::CrossSiteNavigationDataTransfer::Flag> navigationDataTransfer, WebPageProxyIdentifier webPageProxyID, PageIdentifier webPageID)
964 {
965     if (!canSendMessage())
966         return;
967
968     send(Messages::NetworkProcess::DidCommitCrossSiteLoadWithDataTransfer(sessionID, fromDomain, toDomain, navigationDataTransfer, webPageProxyID, webPageID), 0);
969 }
970
971 void NetworkProcessProxy::didCommitCrossSiteLoadWithDataTransferFromPrevalentResource(WebPageProxyIdentifier pageID)
972 {
973     if (!canSendMessage())
974         return;
975
976     WebPageProxy* page = WebProcessProxy::webPage(pageID);
977     if (!page)
978         return;
979
980     page->didCommitCrossSiteLoadWithDataTransferFromPrevalentResource();
981 }
982
983 void NetworkProcessProxy::setCrossSiteLoadWithLinkDecorationForTesting(PAL::SessionID sessionID, const RegistrableDomain& fromDomain, const RegistrableDomain& toDomain, CompletionHandler<void()>&& completionHandler)
984 {
985     if (!canSendMessage()) {
986         completionHandler();
987         return;
988     }
989     
990     sendWithAsyncReply(Messages::NetworkProcess::SetCrossSiteLoadWithLinkDecorationForTesting(sessionID, fromDomain, toDomain), WTFMove(completionHandler));
991 }
992
993 void NetworkProcessProxy::resetCrossSiteLoadsWithLinkDecorationForTesting(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
994 {
995     if (!canSendMessage()) {
996         completionHandler();
997         return;
998     }
999     
1000     sendWithAsyncReply(Messages::NetworkProcess::ResetCrossSiteLoadsWithLinkDecorationForTesting(sessionID), WTFMove(completionHandler));
1001 }
1002
1003 void NetworkProcessProxy::deleteCookiesForTesting(PAL::SessionID sessionID, const RegistrableDomain& domain, bool includeHttpOnlyCookies, CompletionHandler<void()>&& completionHandler)
1004 {
1005     if (!canSendMessage()) {
1006         completionHandler();
1007         return;
1008     }
1009     
1010     sendWithAsyncReply(Messages::NetworkProcess::DeleteCookiesForTesting(sessionID, domain, includeHttpOnlyCookies), WTFMove(completionHandler));
1011 }
1012
1013 void NetworkProcessProxy::deleteWebsiteDataInUIProcessForRegistrableDomains(PAL::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, Vector<RegistrableDomain> domains, CompletionHandler<void(HashSet<WebCore::RegistrableDomain>&&)>&& completionHandler)
1014 {
1015     auto* websiteDataStore = websiteDataStoreFromSessionID(sessionID);
1016     if (!websiteDataStore || dataTypes.isEmpty() || domains.isEmpty()) {
1017         completionHandler({ });
1018         return;
1019     }
1020
1021     websiteDataStore->fetchDataForRegistrableDomains(dataTypes, fetchOptions, domains, [dataTypes, websiteDataStore = makeRef(*websiteDataStore), completionHandler = WTFMove(completionHandler)] (Vector<WebsiteDataRecord>&& matchingDataRecords, HashSet<WebCore::RegistrableDomain>&& domainsWithMatchingDataRecords) mutable {
1022         websiteDataStore->removeData(dataTypes, WTFMove(matchingDataRecords), [domainsWithMatchingDataRecords = WTFMove(domainsWithMatchingDataRecords), completionHandler = WTFMove(completionHandler)] () mutable {
1023             completionHandler(WTFMove(domainsWithMatchingDataRecords));
1024         });
1025     });
1026 }
1027
1028 void NetworkProcessProxy::hasIsolatedSession(PAL::SessionID sessionID, const RegistrableDomain& domain, CompletionHandler<void(bool)>&& completionHandler)
1029 {
1030     if (!canSendMessage()) {
1031         completionHandler(false);
1032         return;
1033     }
1034     
1035     sendWithAsyncReply(Messages::NetworkProcess::HasIsolatedSession(sessionID, domain), WTFMove(completionHandler));
1036 }
1037
1038 void NetworkProcessProxy::setShouldDowngradeReferrerForTesting(bool enabled, CompletionHandler<void()>&& completionHandler)
1039 {
1040     if (!canSendMessage()) {
1041         completionHandler();
1042         return;
1043     }
1044     
1045     sendWithAsyncReply(Messages::NetworkProcess::SetShouldDowngradeReferrerForTesting(enabled), WTFMove(completionHandler));
1046 }
1047 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
1048
1049 void NetworkProcessProxy::sendProcessWillSuspendImminently()
1050 {
1051     if (canSendMessage())
1052         send(Messages::NetworkProcess::ProcessWillSuspendImminently(), 0);
1053 }
1054
1055 void NetworkProcessProxy::sendProcessWillSuspendImminentlyForTesting()
1056 {
1057     if (canSendMessage())
1058         sendSync(Messages::NetworkProcess::ProcessWillSuspendImminentlyForTestingSync(), Messages::NetworkProcess::ProcessWillSuspendImminentlyForTestingSync::Reply(), 0);
1059 }
1060     
1061 void NetworkProcessProxy::sendPrepareToSuspend()
1062 {
1063     if (canSendMessage())
1064         send(Messages::NetworkProcess::PrepareToSuspend(), 0);
1065 }
1066
1067 void NetworkProcessProxy::sendCancelPrepareToSuspend()
1068 {
1069     if (canSendMessage())
1070         send(Messages::NetworkProcess::CancelPrepareToSuspend(), 0);
1071 }
1072
1073 void NetworkProcessProxy::sendProcessDidResume()
1074 {
1075     if (canSendMessage())
1076         send(Messages::NetworkProcess::ProcessDidResume(), 0);
1077 }
1078
1079 void NetworkProcessProxy::processReadyToSuspend()
1080 {
1081     m_throttler.processReadyToSuspend();
1082 }
1083
1084 void NetworkProcessProxy::didSetAssertionState(AssertionState)
1085 {
1086 }
1087     
1088 void NetworkProcessProxy::setIsHoldingLockedFiles(bool isHoldingLockedFiles)
1089 {
1090     if (!isHoldingLockedFiles) {
1091         RELEASE_LOG(ProcessSuspension, "UIProcess is releasing a background assertion because the Network process is no longer holding locked files");
1092         m_tokenForHoldingLockedFiles = nullptr;
1093         return;
1094     }
1095     if (!m_tokenForHoldingLockedFiles) {
1096         RELEASE_LOG(ProcessSuspension, "UIProcess is taking a background assertion because the Network process is holding locked files");
1097         m_tokenForHoldingLockedFiles = m_throttler.backgroundActivityToken();
1098     }
1099 }
1100
1101 void NetworkProcessProxy::syncAllCookies()
1102 {
1103     send(Messages::NetworkProcess::SyncAllCookies(), 0);
1104     
1105     ++m_syncAllCookiesCounter;
1106     if (m_syncAllCookiesToken)
1107         return;
1108     
1109     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is syncing cookies", this);
1110     m_syncAllCookiesToken = throttler().backgroundActivityToken();
1111 }
1112     
1113 void NetworkProcessProxy::didSyncAllCookies()
1114 {
1115     ASSERT(m_syncAllCookiesCounter);
1116
1117     --m_syncAllCookiesCounter;
1118     if (!m_syncAllCookiesCounter) {
1119         RELEASE_LOG(ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done syncing cookies", this);
1120         m_syncAllCookiesToken = nullptr;
1121     }
1122 }
1123
1124 void NetworkProcessProxy::addSession(Ref<WebsiteDataStore>&& store)
1125 {
1126     if (canSendMessage())
1127         send(Messages::NetworkProcess::AddWebsiteDataStore { store->parameters() }, 0);
1128     auto sessionID = store->sessionID();
1129     if (!sessionID.isEphemeral()) {
1130 #if ENABLE(INDEXED_DATABASE)
1131         createSymLinkForFileUpgrade(store->resolvedIndexedDatabaseDirectory());
1132 #endif
1133         m_websiteDataStores.set(sessionID, WTFMove(store));
1134     }
1135 }
1136
1137 void NetworkProcessProxy::removeSession(PAL::SessionID sessionID)
1138 {
1139     if (canSendMessage())
1140         send(Messages::NetworkProcess::DestroySession { sessionID }, 0);
1141     if (!sessionID.isEphemeral())
1142         m_websiteDataStores.remove(sessionID);
1143 }
1144
1145 WebsiteDataStore* NetworkProcessProxy::websiteDataStoreFromSessionID(PAL::SessionID sessionID)
1146 {
1147     auto iterator = m_websiteDataStores.find(sessionID);
1148     if (iterator != m_websiteDataStores.end())
1149         return iterator->value.get();
1150
1151     if (auto* websiteDataStore = m_processPool.websiteDataStore()) {
1152         if (sessionID == websiteDataStore->sessionID())
1153             return websiteDataStore;
1154     }
1155
1156     if (sessionID != PAL::SessionID::defaultSessionID())
1157         return nullptr;
1158
1159     return WebKit::WebsiteDataStore::defaultDataStore().ptr();
1160 }
1161
1162 void NetworkProcessProxy::retrieveCacheStorageParameters(PAL::SessionID sessionID)
1163 {
1164     auto* store = websiteDataStoreFromSessionID(sessionID);
1165
1166     if (!store) {
1167         RELEASE_LOG_ERROR(CacheStorage, "%p - NetworkProcessProxy is unable to retrieve CacheStorage parameters from the given session ID %" PRIu64, this, sessionID.toUInt64());
1168         send(Messages::NetworkProcess::SetCacheStorageParameters { sessionID, { }, { } }, 0);
1169         return;
1170     }
1171
1172     auto& cacheStorageDirectory = store->cacheStorageDirectory();
1173     SandboxExtension::Handle cacheStorageDirectoryExtensionHandle;
1174     if (!cacheStorageDirectory.isEmpty())
1175         SandboxExtension::createHandleForReadWriteDirectory(cacheStorageDirectory, cacheStorageDirectoryExtensionHandle);
1176
1177     send(Messages::NetworkProcess::SetCacheStorageParameters { sessionID, cacheStorageDirectory, cacheStorageDirectoryExtensionHandle }, 0);
1178 }
1179
1180 #if ENABLE(CONTENT_EXTENSIONS)
1181 void NetworkProcessProxy::contentExtensionRules(UserContentControllerIdentifier identifier)
1182 {
1183     if (auto* webUserContentControllerProxy = WebUserContentControllerProxy::get(identifier)) {
1184         m_webUserContentControllerProxies.add(webUserContentControllerProxy);
1185         webUserContentControllerProxy->addNetworkProcess(*this);
1186
1187         auto rules = WTF::map(webUserContentControllerProxy->contentExtensionRules(), [](auto&& keyValue) -> std::pair<String, WebCompiledContentRuleListData> {
1188             return std::make_pair(keyValue.value->name(), keyValue.value->compiledRuleList().data());
1189         });
1190         send(Messages::NetworkContentRuleListManager::AddContentRuleLists { identifier, rules }, 0);
1191         return;
1192     }
1193     send(Messages::NetworkContentRuleListManager::AddContentRuleLists { identifier, { } }, 0);
1194 }
1195
1196 void NetworkProcessProxy::didDestroyWebUserContentControllerProxy(WebUserContentControllerProxy& proxy)
1197 {
1198     send(Messages::NetworkContentRuleListManager::Remove { proxy.identifier() }, 0);
1199     m_webUserContentControllerProxies.remove(&proxy);
1200 }
1201 #endif
1202
1203 void NetworkProcessProxy::sendProcessDidTransitionToForeground()
1204 {
1205     send(Messages::NetworkProcess::ProcessDidTransitionToForeground(), 0);
1206 }
1207
1208 void NetworkProcessProxy::sendProcessDidTransitionToBackground()
1209 {
1210     send(Messages::NetworkProcess::ProcessDidTransitionToBackground(), 0);
1211 }
1212
1213 #if ENABLE(SANDBOX_EXTENSIONS)
1214 void NetworkProcessProxy::getSandboxExtensionsForBlobFiles(const Vector<String>& paths, Messages::NetworkProcessProxy::GetSandboxExtensionsForBlobFiles::AsyncReply&& reply)
1215 {
1216     SandboxExtension::HandleArray extensions;
1217     extensions.allocate(paths.size());
1218     for (size_t i = 0; i < paths.size(); ++i) {
1219         // ReadWrite is required for creating hard links, which is something that might be done with these extensions.
1220         SandboxExtension::createHandle(paths[i], SandboxExtension::Type::ReadWrite, extensions[i]);
1221     }
1222     reply(WTFMove(extensions));
1223 }
1224 #endif
1225
1226 #if ENABLE(SERVICE_WORKER)
1227 void NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcess(RegistrableDomain&& registrableDomain, PAL::SessionID sessionID)
1228 {
1229     m_processPool.establishWorkerContextConnectionToNetworkProcess(*this, WTFMove(registrableDomain), sessionID);
1230 }
1231 #endif
1232
1233 void NetworkProcessProxy::requestStorageSpace(PAL::SessionID sessionID, const WebCore::ClientOrigin& origin, uint64_t currentQuota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&& completionHandler)
1234 {
1235     auto* store = websiteDataStoreFromSessionID(sessionID);
1236
1237     if (!store) {
1238         completionHandler({ });
1239         return;
1240     }
1241
1242     store->client().requestStorageSpace(origin.topOrigin, origin.clientOrigin, currentQuota, currentSize, spaceRequired, [sessionID, origin, currentQuota, currentSize, spaceRequired, completionHandler = WTFMove(completionHandler)](auto quota) mutable {
1243         if (quota) {
1244             completionHandler(quota);
1245             return;
1246         }
1247
1248         if (origin.topOrigin != origin.clientOrigin) {
1249             completionHandler({ });
1250             return;
1251         }
1252
1253         WebPageProxy::forMostVisibleWebPageIfAny(sessionID, origin.topOrigin, [completionHandler = WTFMove(completionHandler), origin, currentQuota, currentSize, spaceRequired](auto* page) mutable {
1254             if (!page) {
1255                 completionHandler({ });
1256                 return;
1257             }
1258             String name = makeString(FileSystem::encodeForFileName(origin.topOrigin.host), " content");
1259             page->requestStorageSpace(page->mainFrame()->frameID(), origin.topOrigin.databaseIdentifier(), name, name, currentQuota, currentSize, currentSize, spaceRequired, [completionHandler = WTFMove(completionHandler)](auto quota) mutable {
1260                 completionHandler(quota);
1261             });
1262         });
1263     });
1264 }
1265
1266 void NetworkProcessProxy::registerSchemeForLegacyCustomProtocol(const String& scheme)
1267 {
1268 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
1269     send(Messages::LegacyCustomProtocolManager::RegisterScheme(scheme), 0);
1270 #else
1271     UNUSED_PARAM(scheme);
1272 #endif
1273 }
1274
1275 void NetworkProcessProxy::unregisterSchemeForLegacyCustomProtocol(const String& scheme)
1276 {
1277 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
1278     send(Messages::LegacyCustomProtocolManager::UnregisterScheme(scheme), 0);
1279 #else
1280     UNUSED_PARAM(scheme);
1281 #endif
1282 }
1283
1284 void NetworkProcessProxy::takeUploadAssertion()
1285 {
1286     ASSERT(!m_uploadAssertion);
1287     m_uploadAssertion = makeUnique<ProcessAssertion>(processIdentifier(), "WebKit uploads"_s, AssertionState::UnboundedNetworking);
1288 }
1289
1290 void NetworkProcessProxy::clearUploadAssertion()
1291 {
1292     ASSERT(m_uploadAssertion);
1293     m_uploadAssertion = nullptr;
1294 }
1295
1296 void NetworkProcessProxy::testProcessIncomingSyncMessagesWhenWaitingForSyncReply(WebPageProxyIdentifier pageID, Messages::NetworkProcessProxy::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::DelayedReply&& reply)
1297 {
1298     auto* page = WebProcessProxy::webPage(pageID);
1299     if (!page)
1300         return reply(false);
1301
1302     bool handled = false;
1303     if (!page->sendSync(Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply(), Messages::WebPage::TestProcessIncomingSyncMessagesWhenWaitingForSyncReply::Reply(handled), Seconds::infinity(), IPC::SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply))
1304         return reply(false);
1305     reply(handled);
1306 }
1307
1308 #if ENABLE(INDEXED_DATABASE)
1309 void NetworkProcessProxy::createSymLinkForFileUpgrade(const String& indexedDatabaseDirectory)
1310 {
1311     if (indexedDatabaseDirectory.isEmpty())
1312         return;
1313
1314     String oldVersionDirectory = FileSystem::pathByAppendingComponent(indexedDatabaseDirectory, "v0");
1315     FileSystem::deleteEmptyDirectory(oldVersionDirectory);
1316     if (!FileSystem::fileExists(oldVersionDirectory))
1317         FileSystem::createSymbolicLink(indexedDatabaseDirectory, oldVersionDirectory);
1318 }
1319 #endif
1320
1321 void NetworkProcessProxy::getLocalStorageDetails(PAL::SessionID sessionID, CompletionHandler<void(Vector<LocalStorageDatabaseTracker::OriginDetails>&&)>&& completionHandler)
1322 {
1323     if (!canSendMessage()) {
1324         completionHandler({ });
1325         return;
1326     }
1327
1328     sendWithAsyncReply(Messages::NetworkProcess::GetLocalStorageOriginDetails(sessionID), WTFMove(completionHandler));
1329 }
1330
1331 } // namespace WebKit
1332
1333 #undef MESSAGE_CHECK
1334 #undef MESSAGE_CHECK_URL