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