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