Add SPI to use networking daemon instead of XPC service
[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 "DownloadProxyMessages.h"
32 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
33 #include "LegacyCustomProtocolManagerProxyMessages.h"
34 #endif
35 #include "Logging.h"
36 #include "NetworkContentRuleListManagerMessages.h"
37 #include "NetworkProcessCreationParameters.h"
38 #include "NetworkProcessMessages.h"
39 #include "SandboxExtension.h"
40 #include "ShouldGrandfatherStatistics.h"
41 #include "StorageAccessStatus.h"
42 #include "WebCompiledContentRuleList.h"
43 #include "WebPageProxy.h"
44 #include "WebProcessMessages.h"
45 #include "WebProcessPool.h"
46 #include "WebProcessProxy.h"
47 #include "WebResourceLoadStatisticsStore.h"
48 #include "WebUserContentControllerProxy.h"
49 #include "WebsiteData.h"
50 #include "WebsiteDataStoreClient.h"
51 #include <WebCore/ClientOrigin.h>
52 #include <wtf/CompletionHandler.h>
53
54 #if ENABLE(SEC_ITEM_SHIM)
55 #include "SecItemShimProxy.h"
56 #endif
57
58 #if PLATFORM(IOS_FAMILY)
59 #include <wtf/spi/darwin/XPCSPI.h>
60 #endif
61
62 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, connection())
63
64 namespace WebKit {
65 using namespace WebCore;
66
67 static uint64_t generateCallbackID()
68 {
69     static uint64_t callbackID;
70
71     return ++callbackID;
72 }
73
74 NetworkProcessProxy::NetworkProcessProxy(WebProcessPool& processPool)
75     : AuxiliaryProcessProxy(processPool.alwaysRunsAtBackgroundPriority())
76     , m_processPool(processPool)
77     , m_numPendingConnectionRequests(0)
78 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
79     , m_customProtocolManagerProxy(*this)
80 #endif
81     , m_throttler(*this, processPool.shouldTakeUIBackgroundAssertion())
82 {
83     connect();
84
85     if (auto* websiteDataStore = m_processPool.websiteDataStore())
86         m_websiteDataStores.set(websiteDataStore->websiteDataStore().sessionID(), makeRef(websiteDataStore->websiteDataStore()));
87 }
88
89 NetworkProcessProxy::~NetworkProcessProxy()
90 {
91     ASSERT(m_pendingFetchWebsiteDataCallbacks.isEmpty());
92     ASSERT(m_pendingDeleteWebsiteDataCallbacks.isEmpty());
93     ASSERT(m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty());
94 #if ENABLE(CONTENT_EXTENSIONS)
95     for (auto* proxy : m_webUserContentControllerProxies)
96         proxy->removeNetworkProcess(*this);
97 #endif
98
99     for (auto& reply : m_pendingConnectionReplies)
100         reply.second({ });
101 }
102
103 void NetworkProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions)
104 {
105     launchOptions.processType = m_processPool.usesNetworkingDaemon() ? ProcessLauncher::ProcessType::NetworkDaemon : ProcessLauncher::ProcessType::Network;
106     AuxiliaryProcessProxy::getLaunchOptions(launchOptions);
107
108     if (processPool().shouldMakeNextNetworkProcessLaunchFailForTesting()) {
109         processPool().setShouldMakeNextNetworkProcessLaunchFailForTesting(false);
110         launchOptions.shouldMakeProcessLaunchFailForTesting = true;
111     }
112 }
113
114 void NetworkProcessProxy::connectionWillOpen(IPC::Connection& connection)
115 {
116 #if ENABLE(SEC_ITEM_SHIM)
117     SecItemShimProxy::singleton().initializeConnection(connection);
118 #else
119     UNUSED_PARAM(connection);
120 #endif
121 }
122
123 void NetworkProcessProxy::processWillShutDown(IPC::Connection& connection)
124 {
125     ASSERT_UNUSED(connection, this->connection() == &connection);
126 }
127
128 void NetworkProcessProxy::getNetworkProcessConnection(WebProcessProxy& webProcessProxy, Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply&& reply)
129 {
130     m_pendingConnectionReplies.append(std::make_pair(makeWeakPtr(webProcessProxy), WTFMove(reply)));
131
132     if (state() == State::Launching) {
133         m_numPendingConnectionRequests++;
134         return;
135     }
136
137     bool isServiceWorkerProcess = false;
138     SecurityOriginData securityOrigin;
139 #if ENABLE(SERVICE_WORKER)
140     if (is<ServiceWorkerProcessProxy>(webProcessProxy)) {
141         isServiceWorkerProcess = true;
142         securityOrigin = downcast<ServiceWorkerProcessProxy>(webProcessProxy).securityOrigin();
143     }
144 #endif
145
146     connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(isServiceWorkerProcess, securityOrigin), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
147 }
148
149 DownloadProxy* NetworkProcessProxy::createDownloadProxy(const ResourceRequest& resourceRequest)
150 {
151     if (!m_downloadProxyMap)
152         m_downloadProxyMap = std::make_unique<DownloadProxyMap>(*this);
153
154     return m_downloadProxyMap->createDownloadProxy(m_processPool, resourceRequest);
155 }
156
157 void NetworkProcessProxy::fetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, OptionSet<WebsiteDataFetchOption> fetchOptions, CompletionHandler<void (WebsiteData)>&& completionHandler)
158 {
159     ASSERT(canSendMessage());
160
161     uint64_t callbackID = generateCallbackID();
162     RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is fetching Website data", this);
163
164     m_pendingFetchWebsiteDataCallbacks.add(callbackID, [this, token = throttler().backgroundActivityToken(), completionHandler = WTFMove(completionHandler), sessionID] (WebsiteData websiteData) mutable {
165 #if RELEASE_LOG_DISABLED
166         UNUSED_PARAM(this);
167         UNUSED_PARAM(sessionID);
168 #endif
169         completionHandler(WTFMove(websiteData));
170         RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done fetching Website data", this);
171     });
172
173     send(Messages::NetworkProcess::FetchWebsiteData(sessionID, dataTypes, fetchOptions, callbackID), 0);
174 }
175
176 void NetworkProcessProxy::deleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> dataTypes, WallTime modifiedSince, CompletionHandler<void ()>&& completionHandler)
177 {
178     auto callbackID = generateCallbackID();
179     RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is deleting Website data", this);
180
181     m_pendingDeleteWebsiteDataCallbacks.add(callbackID, [this, token = throttler().backgroundActivityToken(), completionHandler = WTFMove(completionHandler), sessionID] () mutable {
182 #if RELEASE_LOG_DISABLED
183         UNUSED_PARAM(this);
184         UNUSED_PARAM(sessionID);
185 #endif
186         completionHandler();
187         RELEASE_LOG_IF(sessionID.isAlwaysOnLoggingAllowed(), ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done deleting Website data", this);
188     });
189     send(Messages::NetworkProcess::DeleteWebsiteData(sessionID, dataTypes, modifiedSince, callbackID), 0);
190 }
191
192 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)
193 {
194     ASSERT(canSendMessage());
195
196     uint64_t callbackID = generateCallbackID();
197     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);
198
199     m_pendingDeleteWebsiteDataForOriginsCallbacks.add(callbackID, [this, token = throttler().backgroundActivityToken(), completionHandler = WTFMove(completionHandler), sessionID] () mutable {
200 #if RELEASE_LOG_DISABLED
201         UNUSED_PARAM(this);
202         UNUSED_PARAM(sessionID);
203 #endif
204         completionHandler();
205         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);
206     });
207
208     send(Messages::NetworkProcess::DeleteWebsiteDataForOrigins(sessionID, dataTypes, origins, cookieHostNames, HSTSCacheHostNames, callbackID), 0);
209 }
210
211 void NetworkProcessProxy::networkProcessCrashed()
212 {
213     clearCallbackStates();
214
215     Vector<std::pair<RefPtr<WebProcessProxy>, Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>> pendingReplies;
216     pendingReplies.reserveInitialCapacity(m_pendingConnectionReplies.size());
217     for (auto& reply : m_pendingConnectionReplies) {
218         if (reply.first)
219             pendingReplies.append(std::make_pair(makeRefPtr(reply.first.get()), WTFMove(reply.second)));
220         else
221             reply.second({ });
222     }
223     m_pendingConnectionReplies.clear();
224
225     // Tell the network process manager to forget about this network process proxy. This will cause us to be deleted.
226     m_processPool.networkProcessCrashed(*this, WTFMove(pendingReplies));
227 }
228
229 void NetworkProcessProxy::clearCallbackStates()
230 {
231     while (!m_pendingFetchWebsiteDataCallbacks.isEmpty())
232         m_pendingFetchWebsiteDataCallbacks.take(m_pendingFetchWebsiteDataCallbacks.begin()->key)(WebsiteData { });
233
234     while (!m_pendingDeleteWebsiteDataCallbacks.isEmpty())
235         m_pendingDeleteWebsiteDataCallbacks.take(m_pendingDeleteWebsiteDataCallbacks.begin()->key)();
236
237     while (!m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty())
238         m_pendingDeleteWebsiteDataForOriginsCallbacks.take(m_pendingDeleteWebsiteDataForOriginsCallbacks.begin()->key)();
239 }
240
241 void NetworkProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
242 {
243     if (dispatchMessage(connection, decoder))
244         return;
245
246     if (m_processPool.dispatchMessage(connection, decoder))
247         return;
248
249     didReceiveNetworkProcessProxyMessage(connection, decoder);
250 }
251
252 void NetworkProcessProxy::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
253 {
254     if (dispatchSyncMessage(connection, decoder, replyEncoder))
255         return;
256
257     ASSERT_NOT_REACHED();
258 }
259
260 void NetworkProcessProxy::didClose(IPC::Connection&)
261 {
262     auto protectedProcessPool = makeRef(m_processPool);
263
264     if (m_downloadProxyMap)
265         m_downloadProxyMap->processDidClose();
266 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
267     m_customProtocolManagerProxy.invalidate();
268 #endif
269
270     m_tokenForHoldingLockedFiles = nullptr;
271     
272     m_syncAllCookiesToken = nullptr;
273     m_syncAllCookiesCounter = 0;
274
275     // This will cause us to be deleted.
276     networkProcessCrashed();
277 }
278
279 void NetworkProcessProxy::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
280 {
281 }
282
283 void NetworkProcessProxy::didCreateNetworkConnectionToWebProcess(const IPC::Attachment& connectionIdentifier)
284 {
285     ASSERT(!m_pendingConnectionReplies.isEmpty());
286
287     // Grab the first pending connection reply.
288     auto reply = m_pendingConnectionReplies.takeFirst().second;
289
290 #if USE(UNIX_DOMAIN_SOCKETS) || OS(WINDOWS)
291     reply(connectionIdentifier);
292 #elif OS(DARWIN)
293     MESSAGE_CHECK(MACH_PORT_VALID(connectionIdentifier.port()));
294     reply(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND));
295 #else
296     notImplemented();
297 #endif
298 }
299
300 void NetworkProcessProxy::didReceiveAuthenticationChallenge(uint64_t pageID, uint64_t frameID, WebCore::AuthenticationChallenge&& coreChallenge, uint64_t challengeID)
301 {
302 #if ENABLE(SERVICE_WORKER)
303     if (auto* serviceWorkerProcessProxy = m_processPool.serviceWorkerProcessProxyFromPageID(pageID)) {
304         auto authenticationChallenge = AuthenticationChallengeProxy::create(WTFMove(coreChallenge), challengeID, makeRef(*connection()), nullptr);
305         serviceWorkerProcessProxy->didReceiveAuthenticationChallenge(pageID, frameID, WTFMove(authenticationChallenge));
306         return;
307     }
308 #endif
309
310     WebPageProxy* page = WebProcessProxy::webPage(pageID);
311     MESSAGE_CHECK(page);
312
313     auto authenticationChallenge = AuthenticationChallengeProxy::create(WTFMove(coreChallenge), challengeID, makeRef(*connection()), page->secKeyProxyStore(coreChallenge));
314     page->didReceiveAuthenticationChallengeProxy(frameID, WTFMove(authenticationChallenge));
315 }
316
317 void NetworkProcessProxy::didFetchWebsiteData(uint64_t callbackID, const WebsiteData& websiteData)
318 {
319     auto callback = m_pendingFetchWebsiteDataCallbacks.take(callbackID);
320     callback(websiteData);
321 }
322
323 void NetworkProcessProxy::didDeleteWebsiteData(uint64_t callbackID)
324 {
325     auto callback = m_pendingDeleteWebsiteDataCallbacks.take(callbackID);
326     callback();
327 }
328
329 void NetworkProcessProxy::didDeleteWebsiteDataForOrigins(uint64_t callbackID)
330 {
331     auto callback = m_pendingDeleteWebsiteDataForOriginsCallbacks.take(callbackID);
332     callback();
333 }
334
335 void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier)
336 {
337     AuxiliaryProcessProxy::didFinishLaunching(launcher, connectionIdentifier);
338
339     if (!IPC::Connection::identifierIsValid(connectionIdentifier)) {
340         networkProcessCrashed();
341         return;
342     }
343
344     for (unsigned i = 0; i < m_numPendingConnectionRequests; ++i)
345         connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(false, { }), 0);
346     
347     m_numPendingConnectionRequests = 0;
348
349 #if PLATFORM(COCOA)
350     if (m_processPool.processSuppressionEnabled())
351         setProcessSuppressionEnabled(true);
352 #endif
353     
354 #if PLATFORM(IOS_FAMILY)
355     if (xpc_connection_t connection = this->connection()->xpcConnection())
356         m_throttler.didConnectToProcess(xpc_connection_get_pid(connection));
357 #endif
358 }
359
360 void NetworkProcessProxy::logDiagnosticMessage(uint64_t pageID, const String& message, const String& description, WebCore::ShouldSample shouldSample)
361 {
362     WebPageProxy* page = WebProcessProxy::webPage(pageID);
363     // 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,
364     // but for now we simply drop the message in the rare case this happens.
365     if (!page)
366         return;
367
368     page->logDiagnosticMessage(message, description, shouldSample);
369 }
370
371 void NetworkProcessProxy::logDiagnosticMessageWithResult(uint64_t pageID, const String& message, const String& description, uint32_t result, WebCore::ShouldSample shouldSample)
372 {
373     WebPageProxy* page = WebProcessProxy::webPage(pageID);
374     // 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,
375     // but for now we simply drop the message in the rare case this happens.
376     if (!page)
377         return;
378
379     page->logDiagnosticMessageWithResult(message, description, result, shouldSample);
380 }
381
382 void NetworkProcessProxy::logDiagnosticMessageWithValue(uint64_t pageID, const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample shouldSample)
383 {
384     WebPageProxy* page = WebProcessProxy::webPage(pageID);
385     // 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,
386     // but for now we simply drop the message in the rare case this happens.
387     if (!page)
388         return;
389
390     page->logDiagnosticMessageWithValue(message, description, value, significantFigures, shouldSample);
391 }
392
393 void NetworkProcessProxy::logGlobalDiagnosticMessageWithValue(const String& message, const String& description, double value, unsigned significantFigures, WebCore::ShouldSample shouldSample)
394 {
395     if (auto* page = WebPageProxy::nonEphemeralWebPageProxy())
396         page->logDiagnosticMessageWithValue(message, description, value, significantFigures, shouldSample);
397 }
398
399 #if ENABLE(RESOURCE_LOAD_STATISTICS)
400 void NetworkProcessProxy::dumpResourceLoadStatistics(PAL::SessionID sessionID, CompletionHandler<void(String)>&& completionHandler)
401 {
402     if (!canSendMessage()) {
403         completionHandler({ });
404         return;
405     }
406     
407     sendWithAsyncReply(Messages::NetworkProcess::DumpResourceLoadStatistics(sessionID), WTFMove(completionHandler));
408 }
409
410 void NetworkProcessProxy::updatePrevalentDomainsToBlockCookiesFor(PAL::SessionID sessionID, const Vector<String>& domainsToBlock, CompletionHandler<void()>&& completionHandler)
411 {
412     if (!canSendMessage()) {
413         completionHandler();
414         return;
415     }
416
417     sendWithAsyncReply(Messages::NetworkProcess::UpdatePrevalentDomainsToBlockCookiesFor(sessionID, domainsToBlock), WTFMove(completionHandler));
418 }
419
420 void NetworkProcessProxy::isPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
421 {
422     if (!canSendMessage()) {
423         completionHandler(false);
424         return;
425     }
426
427     sendWithAsyncReply(Messages::NetworkProcess::IsPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
428 }
429
430 void NetworkProcessProxy::isVeryPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
431 {
432     if (!canSendMessage()) {
433         completionHandler(false);
434         return;
435     }
436
437     sendWithAsyncReply(Messages::NetworkProcess::IsVeryPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
438 }
439
440 void NetworkProcessProxy::setPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
441 {
442     if (!canSendMessage()) {
443         completionHandler();
444         return;
445     }
446
447     sendWithAsyncReply(Messages::NetworkProcess::SetPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
448 }
449
450 void NetworkProcessProxy::setPrevalentResourceForDebugMode(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
451 {
452     if (!canSendMessage()) {
453         completionHandler();
454         return;
455     }
456
457     sendWithAsyncReply(Messages::NetworkProcess::SetPrevalentResourceForDebugMode(sessionID, resourceDomain), WTFMove(completionHandler));
458 }
459
460 void NetworkProcessProxy::setVeryPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
461 {
462     if (!canSendMessage()) {
463         completionHandler();
464         return;
465     }
466
467     sendWithAsyncReply(Messages::NetworkProcess::SetVeryPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
468 }
469
470 void NetworkProcessProxy::setLastSeen(PAL::SessionID sessionID, const String& resourceDomain, Seconds lastSeen, CompletionHandler<void()>&& completionHandler)
471 {
472     if (!canSendMessage()) {
473         completionHandler();
474         return;
475     }
476     
477     sendWithAsyncReply(Messages::NetworkProcess::SetLastSeen(sessionID, resourceDomain, lastSeen), WTFMove(completionHandler));
478 }
479
480 void NetworkProcessProxy::clearPrevalentResource(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
481 {
482     if (!canSendMessage()) {
483         completionHandler();
484         return;
485     }
486     
487     sendWithAsyncReply(Messages::NetworkProcess::ClearPrevalentResource(sessionID, resourceDomain), WTFMove(completionHandler));
488 }
489     
490 void NetworkProcessProxy::scheduleCookieBlockingUpdate(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
491 {
492     if (!canSendMessage()) {
493         completionHandler();
494         return;
495     }
496     
497     sendWithAsyncReply(Messages::NetworkProcess::ScheduleCookieBlockingUpdate(sessionID), WTFMove(completionHandler));
498 }
499
500 void NetworkProcessProxy::scheduleClearInMemoryAndPersistent(PAL::SessionID sessionID, Optional<WallTime> modifiedSince, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
501 {
502     if (!canSendMessage()) {
503         completionHandler();
504         return;
505     }
506
507     sendWithAsyncReply(Messages::NetworkProcess::ScheduleClearInMemoryAndPersistent(sessionID, modifiedSince, shouldGrandfather), WTFMove(completionHandler));
508 }
509
510 void NetworkProcessProxy::scheduleStatisticsAndDataRecordsProcessing(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
511 {
512     if (!canSendMessage()) {
513         completionHandler();
514         return;
515     }
516     
517     sendWithAsyncReply(Messages::NetworkProcess::ScheduleStatisticsAndDataRecordsProcessing(sessionID), WTFMove(completionHandler));
518 }
519
520 void NetworkProcessProxy::logUserInteraction(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
521 {
522     if (!canSendMessage()) {
523         completionHandler();
524         return;
525     }
526
527     sendWithAsyncReply(Messages::NetworkProcess::LogUserInteraction(sessionID, resourceDomain), WTFMove(completionHandler));
528 }
529
530 void NetworkProcessProxy::hasHadUserInteraction(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
531 {
532     if (!canSendMessage()) {
533         completionHandler(false);
534         return;
535     }
536     
537     sendWithAsyncReply(Messages::NetworkProcess::HadUserInteraction(sessionID, resourceDomain), WTFMove(completionHandler));
538 }
539
540 void NetworkProcessProxy::clearUserInteraction(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void()>&& completionHandler)
541 {
542     if (!canSendMessage()) {
543         completionHandler();
544         return;
545     }
546     
547     sendWithAsyncReply(Messages::NetworkProcess::ClearUserInteraction(sessionID, resourceDomain), WTFMove(completionHandler));
548 }
549
550 void NetworkProcessProxy::setAgeCapForClientSideCookies(PAL::SessionID sessionID, Optional<Seconds> seconds, CompletionHandler<void()>&& completionHandler)
551 {
552     if (!canSendMessage()) {
553         completionHandler();
554         return;
555     }
556     
557     sendWithAsyncReply(Messages::NetworkProcess::SetAgeCapForClientSideCookies(sessionID, seconds), WTFMove(completionHandler));
558 }
559
560 void NetworkProcessProxy::setTimeToLiveUserInteraction(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
561 {
562     if (!canSendMessage()) {
563         completionHandler();
564         return;
565     }
566     
567     sendWithAsyncReply(Messages::NetworkProcess::SetTimeToLiveUserInteraction(sessionID, seconds), WTFMove(completionHandler));
568 }
569
570 void NetworkProcessProxy::setNotifyPagesWhenTelemetryWasCaptured(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
571 {
572     if (!canSendMessage()) {
573         completionHandler();
574         return;
575     }
576     
577     sendWithAsyncReply(Messages::NetworkProcess::SetNotifyPagesWhenTelemetryWasCaptured(sessionID, value), WTFMove(completionHandler));
578 }
579
580 void NetworkProcessProxy::setNotifyPagesWhenDataRecordsWereScanned(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
581 {
582     if (!canSendMessage()) {
583         completionHandler();
584         return;
585     }
586     
587     sendWithAsyncReply(Messages::NetworkProcess::SetNotifyPagesWhenDataRecordsWereScanned(sessionID, value), WTFMove(completionHandler));
588 }
589
590 void NetworkProcessProxy::setSubframeUnderTopFrameOrigin(PAL::SessionID sessionID, const String& subframe, const String& topFrame, CompletionHandler<void()>&& completionHandler)
591 {
592     if (!canSendMessage()) {
593         completionHandler();
594         return;
595     }
596     
597     sendWithAsyncReply(Messages::NetworkProcess::SetSubframeUnderTopFrameOrigin(sessionID, subframe, topFrame), WTFMove(completionHandler));
598 }
599
600 void NetworkProcessProxy::isRegisteredAsRedirectingTo(PAL::SessionID sessionID, const String& redirectedFrom, const String& redirectedTo, CompletionHandler<void(bool)>&& completionHandler)
601 {
602     if (!canSendMessage()) {
603         completionHandler(false);
604         return;
605     }
606     
607     sendWithAsyncReply(Messages::NetworkProcess::IsRegisteredAsRedirectingTo(sessionID, redirectedFrom, redirectedTo), WTFMove(completionHandler));
608 }
609
610 void NetworkProcessProxy::isRegisteredAsSubFrameUnder(PAL::SessionID sessionID, const String& subFrame, const String& topFrame, CompletionHandler<void(bool)>&& completionHandler)
611 {
612     if (!canSendMessage()) {
613         completionHandler(false);
614         return;
615     }
616     
617     sendWithAsyncReply(Messages::NetworkProcess::IsRegisteredAsSubFrameUnder(sessionID, subFrame, topFrame), WTFMove(completionHandler));
618 }
619
620 void NetworkProcessProxy::setSubresourceUnderTopFrameOrigin(PAL::SessionID sessionID, const String& subresource, const String& topFrame, CompletionHandler<void()>&& completionHandler)
621 {
622     if (!canSendMessage()) {
623         completionHandler();
624         return;
625     }
626     
627     sendWithAsyncReply(Messages::NetworkProcess::SetSubresourceUnderTopFrameOrigin(sessionID, subresource, topFrame), WTFMove(completionHandler));
628 }
629
630 void NetworkProcessProxy::isRegisteredAsSubresourceUnder(PAL::SessionID sessionID, const String& subresource, const String& topFrame, CompletionHandler<void(bool)>&& completionHandler)
631 {
632     if (!canSendMessage()) {
633         completionHandler(false);
634         return;
635     }
636     
637     sendWithAsyncReply(Messages::NetworkProcess::IsRegisteredAsSubresourceUnder(sessionID, subresource, topFrame), WTFMove(completionHandler));
638 }
639
640 void NetworkProcessProxy::setSubresourceUniqueRedirectTo(PAL::SessionID sessionID, const String& subresource, const String& hostNameRedirectedTo, CompletionHandler<void()>&& completionHandler)
641 {
642     if (!canSendMessage()) {
643         completionHandler();
644         return;
645     }
646     
647     sendWithAsyncReply(Messages::NetworkProcess::SetSubresourceUniqueRedirectTo(sessionID, subresource, hostNameRedirectedTo), WTFMove(completionHandler));
648 }
649
650 void NetworkProcessProxy::setSubresourceUniqueRedirectFrom(PAL::SessionID sessionID, const String& subresource, const String& hostNameRedirectedFrom, CompletionHandler<void()>&& completionHandler)
651 {
652     if (!canSendMessage()) {
653         completionHandler();
654         return;
655     }
656     
657     sendWithAsyncReply(Messages::NetworkProcess::SetSubresourceUniqueRedirectFrom(sessionID, subresource, hostNameRedirectedFrom), WTFMove(completionHandler));
658 }
659
660 void NetworkProcessProxy::setTopFrameUniqueRedirectTo(PAL::SessionID sessionID, const String& topFrameHostName, const String& hostNameRedirectedTo, CompletionHandler<void()>&& completionHandler)
661 {
662     if (!canSendMessage()) {
663         completionHandler();
664         return;
665     }
666     
667     sendWithAsyncReply(Messages::NetworkProcess::SetTopFrameUniqueRedirectTo(sessionID, topFrameHostName, hostNameRedirectedTo), WTFMove(completionHandler));
668 }
669
670 void NetworkProcessProxy::setTopFrameUniqueRedirectFrom(PAL::SessionID sessionID, const String& topFrameHostName, const String& hostNameRedirectedFrom, CompletionHandler<void()>&& completionHandler)
671 {
672     if (!canSendMessage()) {
673         completionHandler();
674         return;
675     }
676     
677     sendWithAsyncReply(Messages::NetworkProcess::SetTopFrameUniqueRedirectFrom(sessionID, topFrameHostName, hostNameRedirectedFrom), WTFMove(completionHandler));
678 }
679
680 void NetworkProcessProxy::isGrandfathered(PAL::SessionID sessionID, const String& resourceDomain, CompletionHandler<void(bool)>&& completionHandler)
681 {
682     if (!canSendMessage()) {
683         completionHandler(false);
684         return;
685     }
686     
687     sendWithAsyncReply(Messages::NetworkProcess::IsGrandfathered(sessionID, resourceDomain), WTFMove(completionHandler));
688 }
689
690 void NetworkProcessProxy::setGrandfathered(PAL::SessionID sessionID, const String& resourceDomain, bool isGrandfathered, CompletionHandler<void()>&& completionHandler)
691 {
692     if (!canSendMessage()) {
693         completionHandler();
694         return;
695     }
696     
697     sendWithAsyncReply(Messages::NetworkProcess::SetGrandfathered(sessionID, resourceDomain, isGrandfathered), WTFMove(completionHandler));
698 }
699
700 void NetworkProcessProxy::hasStorageAccessForFrame(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, uint64_t frameID, uint64_t pageID, CompletionHandler<void(bool)>&& completionHandler)
701 {
702     if (!canSendMessage()) {
703         completionHandler(false);
704         return;
705     }
706
707     sendWithAsyncReply(Messages::NetworkProcess::HasStorageAccessForFrame(sessionID, resourceDomain, firstPartyDomain, frameID, pageID), WTFMove(completionHandler));
708 }
709
710 void NetworkProcessProxy::hasStorageAccess(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID, CompletionHandler<void(bool)>&& completionHandler)
711 {
712     if (!canSendMessage()) {
713         completionHandler(false);
714         return;
715     }
716     
717     sendWithAsyncReply(Messages::NetworkProcess::HasStorageAccess(sessionID, resourceDomain, firstPartyDomain, frameID, pageID), WTFMove(completionHandler));
718 }
719
720 void NetworkProcessProxy::requestStorageAccess(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID, bool promptEnabled, CompletionHandler<void(StorageAccessStatus)>&& completionHandler)
721 {
722     if (!canSendMessage()) {
723         completionHandler(StorageAccessStatus::CannotRequestAccess);
724         return;
725     }
726
727     sendWithAsyncReply(Messages::NetworkProcess::RequestStorageAccess(sessionID, resourceDomain, firstPartyDomain, frameID, pageID, promptEnabled), WTFMove(completionHandler));
728 }
729
730 void NetworkProcessProxy::requestStorageAccessConfirm(uint64_t pageID, uint64_t frameID, const String& subFrameHost, const String& topFrameHost, CompletionHandler<void(bool)>&& completionHandler)
731 {
732     WebPageProxy* page = WebProcessProxy::webPage(pageID);
733     if (!page) {
734         completionHandler(false);
735         return;
736     }
737     
738     page->requestStorageAccessConfirm(subFrameHost, topFrameHost, frameID, WTFMove(completionHandler));
739 }
740
741 void NetworkProcessProxy::grantStorageAccess(PAL::SessionID sessionID, const String& resourceDomain, const String& firstPartyDomain, Optional<uint64_t> frameID, uint64_t pageID, bool userWasPrompted, CompletionHandler<void(bool)>&& completionHandler)
742 {
743     if (!canSendMessage()) {
744         completionHandler(false);
745         return;
746     }
747
748     sendWithAsyncReply(Messages::NetworkProcess::GrantStorageAccess(sessionID, resourceDomain, firstPartyDomain, frameID.value(), pageID, userWasPrompted), WTFMove(completionHandler));
749 }
750
751 void NetworkProcessProxy::removeAllStorageAccess(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
752 {
753     if (!canSendMessage()) {
754         completionHandler();
755         return;
756     }
757
758     sendWithAsyncReply(Messages::NetworkProcess::RemoveAllStorageAccess(sessionID), WTFMove(completionHandler));
759 }
760
761 void NetworkProcessProxy::getAllStorageAccessEntries(PAL::SessionID sessionID, CompletionHandler<void(Vector<String> domains)>&& completionHandler)
762 {
763     if (!canSendMessage()) {
764         completionHandler({ });
765         return;
766     }
767
768     sendWithAsyncReply(Messages::NetworkProcess::GetAllStorageAccessEntries(sessionID), WTFMove(completionHandler));
769 }
770
771 void NetworkProcessProxy::setCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
772 {
773     if (!canSendMessage()) {
774         completionHandler();
775         return;
776     }
777
778     sendWithAsyncReply(Messages::NetworkProcess::SetCacheMaxAgeCapForPrevalentResources(sessionID, seconds), WTFMove(completionHandler));
779 }
780
781 void NetworkProcessProxy::setCacheMaxAgeCap(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
782 {
783     if (!canSendMessage()) {
784         completionHandler();
785         return;
786     }
787     
788     sendWithAsyncReply(Messages::NetworkProcess::SetCacheMaxAgeCapForPrevalentResources(sessionID, seconds), WTFMove(completionHandler));
789 }
790
791 void NetworkProcessProxy::setGrandfatheringTime(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
792 {
793     if (!canSendMessage()) {
794         completionHandler();
795         return;
796     }
797     
798     sendWithAsyncReply(Messages::NetworkProcess::SetGrandfatheringTime(sessionID, seconds), WTFMove(completionHandler));
799 }
800
801 void NetworkProcessProxy::setMaxStatisticsEntries(PAL::SessionID sessionID, size_t maximumEntryCount, CompletionHandler<void()>&& completionHandler)
802 {
803     if (!canSendMessage()) {
804         completionHandler();
805         return;
806     }
807
808     sendWithAsyncReply(Messages::NetworkProcess::SetMaxStatisticsEntries(sessionID, maximumEntryCount), WTFMove(completionHandler));
809 }
810
811 void NetworkProcessProxy::setMinimumTimeBetweenDataRecordsRemoval(PAL::SessionID sessionID, Seconds seconds, CompletionHandler<void()>&& completionHandler)
812 {
813     if (!canSendMessage()) {
814         completionHandler();
815         return;
816     }
817     
818     sendWithAsyncReply(Messages::NetworkProcess::SetMinimumTimeBetweenDataRecordsRemoval(sessionID, seconds), WTFMove(completionHandler));
819 }
820
821 void NetworkProcessProxy::setPruneEntriesDownTo(PAL::SessionID sessionID, size_t pruneTargetCount, CompletionHandler<void()>&& completionHandler)
822 {
823     if (!canSendMessage()) {
824         completionHandler();
825         return;
826     }
827
828     sendWithAsyncReply(Messages::NetworkProcess::SetPruneEntriesDownTo(sessionID, pruneTargetCount), WTFMove(completionHandler));
829 }
830
831 void NetworkProcessProxy::setShouldClassifyResourcesBeforeDataRecordsRemoval(PAL::SessionID sessionID, bool value, CompletionHandler<void()>&& completionHandler)
832 {
833     if (!canSendMessage()) {
834         completionHandler();
835         return;
836     }
837     
838     sendWithAsyncReply(Messages::NetworkProcess::SetShouldClassifyResourcesBeforeDataRecordsRemoval(sessionID, value), WTFMove(completionHandler));
839 }
840
841 void NetworkProcessProxy::setResourceLoadStatisticsDebugMode(PAL::SessionID sessionID, bool debugMode, CompletionHandler<void()>&& completionHandler)
842 {
843     if (!canSendMessage()) {
844         completionHandler();
845         return;
846     }
847     
848     sendWithAsyncReply(Messages::NetworkProcess::SetResourceLoadStatisticsDebugMode(sessionID, debugMode), WTFMove(completionHandler));
849 }
850
851 void NetworkProcessProxy::resetCacheMaxAgeCapForPrevalentResources(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
852 {
853     if (!canSendMessage()) {
854         completionHandler();
855         return;
856     }
857     
858     sendWithAsyncReply(Messages::NetworkProcess::ResetCacheMaxAgeCapForPrevalentResources(sessionID), WTFMove(completionHandler));
859 }
860
861 void NetworkProcessProxy::resetParametersToDefaultValues(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
862 {
863     if (!canSendMessage()) {
864         completionHandler();
865         return;
866     }
867     
868     sendWithAsyncReply(Messages::NetworkProcess::ResetParametersToDefaultValues(sessionID), WTFMove(completionHandler));
869 }
870
871 void NetworkProcessProxy::submitTelemetry(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)
872 {
873     if (!canSendMessage()) {
874         completionHandler();
875         return;
876     }
877     
878     sendWithAsyncReply(Messages::NetworkProcess::SubmitTelemetry(sessionID), WTFMove(completionHandler));
879 }
880
881 void NetworkProcessProxy::scheduleClearInMemoryAndPersistent(PAL::SessionID sessionID, ShouldGrandfatherStatistics shouldGrandfather, CompletionHandler<void()>&& completionHandler)
882 {
883     if (!canSendMessage()) {
884         completionHandler();
885         return;
886     }
887
888     sendWithAsyncReply(Messages::NetworkProcess::ScheduleClearInMemoryAndPersistent(sessionID, { }, shouldGrandfather), WTFMove(completionHandler));
889 }
890
891 void NetworkProcessProxy::logTestingEvent(PAL::SessionID sessionID, const String& event)
892 {
893     if (auto* websiteDataStore = websiteDataStoreFromSessionID(sessionID))
894         websiteDataStore->logTestingEvent(event);
895 }
896
897 void NetworkProcessProxy::notifyResourceLoadStatisticsProcessed()
898 {
899     WebProcessProxy::notifyPageStatisticsAndDataRecordsProcessed();
900 }
901
902 void NetworkProcessProxy::notifyWebsiteDataDeletionForTopPrivatelyOwnedDomainsFinished()
903 {
904     WebProcessProxy::notifyWebsiteDataDeletionForTopPrivatelyOwnedDomainsFinished();
905 }
906
907 void NetworkProcessProxy::notifyWebsiteDataScanForTopPrivatelyControlledDomainsFinished()
908 {
909     WebProcessProxy::notifyWebsiteDataScanForTopPrivatelyControlledDomainsFinished();
910 }
911
912 void NetworkProcessProxy::notifyResourceLoadStatisticsTelemetryFinished(unsigned totalPrevalentResources, unsigned totalPrevalentResourcesWithUserInteraction, unsigned top3SubframeUnderTopFrameOrigins)
913 {
914     API::Dictionary::MapType messageBody;
915     messageBody.set("TotalPrevalentResources"_s, API::UInt64::create(totalPrevalentResources));
916     messageBody.set("TotalPrevalentResourcesWithUserInteraction"_s, API::UInt64::create(totalPrevalentResourcesWithUserInteraction));
917     messageBody.set("Top3SubframeUnderTopFrameOrigins"_s, API::UInt64::create(top3SubframeUnderTopFrameOrigins));
918
919     WebProcessProxy::notifyPageStatisticsTelemetryFinished(API::Dictionary::create(messageBody).ptr());
920 }
921 #endif // ENABLE(RESOURCE_LOAD_STATISTICS)
922
923 void NetworkProcessProxy::sendProcessWillSuspendImminently()
924 {
925     if (!canSendMessage())
926         return;
927
928     bool handled = false;
929     sendSync(Messages::NetworkProcess::ProcessWillSuspendImminently(), Messages::NetworkProcess::ProcessWillSuspendImminently::Reply(handled), 0, 1_s);
930 }
931     
932 void NetworkProcessProxy::sendPrepareToSuspend()
933 {
934     if (canSendMessage())
935         send(Messages::NetworkProcess::PrepareToSuspend(), 0);
936 }
937
938 void NetworkProcessProxy::sendCancelPrepareToSuspend()
939 {
940     if (canSendMessage())
941         send(Messages::NetworkProcess::CancelPrepareToSuspend(), 0);
942 }
943
944 void NetworkProcessProxy::sendProcessDidResume()
945 {
946     if (canSendMessage())
947         send(Messages::NetworkProcess::ProcessDidResume(), 0);
948 }
949
950 void NetworkProcessProxy::processReadyToSuspend()
951 {
952     m_throttler.processReadyToSuspend();
953 }
954
955 void NetworkProcessProxy::didSetAssertionState(AssertionState)
956 {
957 }
958     
959 void NetworkProcessProxy::setIsHoldingLockedFiles(bool isHoldingLockedFiles)
960 {
961     if (!isHoldingLockedFiles) {
962         RELEASE_LOG(ProcessSuspension, "UIProcess is releasing a background assertion because the Network process is no longer holding locked files");
963         m_tokenForHoldingLockedFiles = nullptr;
964         return;
965     }
966     if (!m_tokenForHoldingLockedFiles) {
967         RELEASE_LOG(ProcessSuspension, "UIProcess is taking a background assertion because the Network process is holding locked files");
968         m_tokenForHoldingLockedFiles = m_throttler.backgroundActivityToken();
969     }
970 }
971
972 void NetworkProcessProxy::syncAllCookies()
973 {
974     send(Messages::NetworkProcess::SyncAllCookies(), 0);
975     
976     ++m_syncAllCookiesCounter;
977     if (m_syncAllCookiesToken)
978         return;
979     
980     RELEASE_LOG(ProcessSuspension, "%p - NetworkProcessProxy is taking a background assertion because the Network process is syncing cookies", this);
981     m_syncAllCookiesToken = throttler().backgroundActivityToken();
982 }
983     
984 void NetworkProcessProxy::didSyncAllCookies()
985 {
986     ASSERT(m_syncAllCookiesCounter);
987
988     --m_syncAllCookiesCounter;
989     if (!m_syncAllCookiesCounter) {
990         RELEASE_LOG(ProcessSuspension, "%p - NetworkProcessProxy is releasing a background assertion because the Network process is done syncing cookies", this);
991         m_syncAllCookiesToken = nullptr;
992     }
993 }
994
995 void NetworkProcessProxy::addSession(Ref<WebsiteDataStore>&& store)
996 {
997     if (canSendMessage())
998         send(Messages::NetworkProcess::AddWebsiteDataStore { store->parameters() }, 0);
999     auto sessionID = store->sessionID();
1000     if (!sessionID.isEphemeral())
1001         m_websiteDataStores.set(sessionID, WTFMove(store));
1002 }
1003
1004 void NetworkProcessProxy::removeSession(PAL::SessionID sessionID)
1005 {
1006     if (canSendMessage())
1007         send(Messages::NetworkProcess::DestroySession { sessionID }, 0);
1008     if (!sessionID.isEphemeral())
1009         m_websiteDataStores.remove(sessionID);
1010 }
1011
1012 WebsiteDataStore* NetworkProcessProxy::websiteDataStoreFromSessionID(PAL::SessionID sessionID)
1013 {
1014     auto iterator = m_websiteDataStores.find(sessionID);
1015     if (iterator != m_websiteDataStores.end())
1016         return iterator->value.get();
1017
1018     if (auto* websiteDataStore = m_processPool.websiteDataStore()) {
1019         if (sessionID == websiteDataStore->websiteDataStore().sessionID())
1020             return &websiteDataStore->websiteDataStore();
1021     }
1022
1023     if (sessionID != PAL::SessionID::defaultSessionID())
1024         return nullptr;
1025
1026     return &API::WebsiteDataStore::defaultDataStore()->websiteDataStore();
1027 }
1028
1029 void NetworkProcessProxy::retrieveCacheStorageParameters(PAL::SessionID sessionID)
1030 {
1031     auto* store = websiteDataStoreFromSessionID(sessionID);
1032
1033     if (!store) {
1034         RELEASE_LOG_ERROR(CacheStorage, "%p - NetworkProcessProxy is unable to retrieve CacheStorage parameters from the given session ID %" PRIu64, this, sessionID.sessionID());
1035         auto quota = m_processPool.websiteDataStore() ? m_processPool.websiteDataStore()->websiteDataStore().cacheStoragePerOriginQuota() : WebsiteDataStoreConfiguration::defaultCacheStoragePerOriginQuota;
1036         send(Messages::NetworkProcess::SetCacheStorageParameters { sessionID, quota, { }, { } }, 0);
1037         return;
1038     }
1039
1040     auto& cacheStorageDirectory = store->cacheStorageDirectory();
1041     SandboxExtension::Handle cacheStorageDirectoryExtensionHandle;
1042     if (!cacheStorageDirectory.isEmpty())
1043         SandboxExtension::createHandleForReadWriteDirectory(cacheStorageDirectory, cacheStorageDirectoryExtensionHandle);
1044
1045     send(Messages::NetworkProcess::SetCacheStorageParameters { sessionID, store->cacheStoragePerOriginQuota(), cacheStorageDirectory, cacheStorageDirectoryExtensionHandle }, 0);
1046 }
1047
1048 #if ENABLE(CONTENT_EXTENSIONS)
1049 void NetworkProcessProxy::contentExtensionRules(UserContentControllerIdentifier identifier)
1050 {
1051     if (auto* webUserContentControllerProxy = WebUserContentControllerProxy::get(identifier)) {
1052         m_webUserContentControllerProxies.add(webUserContentControllerProxy);
1053         webUserContentControllerProxy->addNetworkProcess(*this);
1054
1055         auto rules = WTF::map(webUserContentControllerProxy->contentExtensionRules(), [](auto&& keyValue) -> std::pair<String, WebCompiledContentRuleListData> {
1056             return std::make_pair(keyValue.value->name(), keyValue.value->compiledRuleList().data());
1057         });
1058         send(Messages::NetworkContentRuleListManager::AddContentRuleLists { identifier, rules }, 0);
1059         return;
1060     }
1061     send(Messages::NetworkContentRuleListManager::AddContentRuleLists { identifier, { } }, 0);
1062 }
1063
1064 void NetworkProcessProxy::didDestroyWebUserContentControllerProxy(WebUserContentControllerProxy& proxy)
1065 {
1066     send(Messages::NetworkContentRuleListManager::Remove { proxy.identifier() }, 0);
1067     m_webUserContentControllerProxies.remove(&proxy);
1068 }
1069 #endif
1070     
1071 void NetworkProcessProxy::sendProcessDidTransitionToForeground()
1072 {
1073     send(Messages::NetworkProcess::ProcessDidTransitionToForeground(), 0);
1074 }
1075
1076 void NetworkProcessProxy::sendProcessDidTransitionToBackground()
1077 {
1078     send(Messages::NetworkProcess::ProcessDidTransitionToBackground(), 0);
1079 }
1080
1081 #if ENABLE(SANDBOX_EXTENSIONS)
1082 void NetworkProcessProxy::getSandboxExtensionsForBlobFiles(const Vector<String>& paths, Messages::NetworkProcessProxy::GetSandboxExtensionsForBlobFiles::AsyncReply&& reply)
1083 {
1084     SandboxExtension::HandleArray extensions;
1085     extensions.allocate(paths.size());
1086     for (size_t i = 0; i < paths.size(); ++i) {
1087         // ReadWrite is required for creating hard links, which is something that might be done with these extensions.
1088         SandboxExtension::createHandle(paths[i], SandboxExtension::Type::ReadWrite, extensions[i]);
1089     }
1090     reply(WTFMove(extensions));
1091 }
1092 #endif
1093
1094 #if ENABLE(SERVICE_WORKER)
1095 void NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcess(SecurityOriginData&& origin)
1096 {
1097     m_processPool.establishWorkerContextConnectionToNetworkProcess(*this, WTFMove(origin), WTF::nullopt);
1098 }
1099
1100 void NetworkProcessProxy::establishWorkerContextConnectionToNetworkProcessForExplicitSession(SecurityOriginData&& origin, PAL::SessionID sessionID)
1101 {
1102     m_processPool.establishWorkerContextConnectionToNetworkProcess(*this, WTFMove(origin), sessionID);
1103 }
1104 #endif
1105
1106 void NetworkProcessProxy::requestCacheStorageSpace(PAL::SessionID sessionID, const WebCore::ClientOrigin& origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&& completionHandler)
1107 {
1108     auto* store = websiteDataStoreFromSessionID(sessionID);
1109
1110     if (!store) {
1111         completionHandler({ });
1112         return;
1113     }
1114
1115     store->client().requestCacheStorageSpace(origin.topOrigin, origin.clientOrigin, quota, currentSize, spaceRequired, WTFMove(completionHandler));
1116 }
1117
1118 } // namespace WebKit
1119
1120 #undef MESSAGE_CHECK
1121 #undef MESSAGE_CHECK_URL