Get rid of IconDatabase related code in WebKit.
[WebKit-https.git] / Source / WebKit / UIProcess / WebProcessPool.cpp
1 /*
2  * Copyright (C) 2010-2017 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 "WebProcessPool.h"
28
29 #include "APIArray.h"
30 #include "APIAutomationClient.h"
31 #include "APICustomProtocolManagerClient.h"
32 #include "APIDownloadClient.h"
33 #include "APIHTTPCookieStore.h"
34 #include "APIInjectedBundleClient.h"
35 #include "APILegacyContextHistoryClient.h"
36 #include "APIPageConfiguration.h"
37 #include "APIProcessPoolConfiguration.h"
38 #include "DownloadProxy.h"
39 #include "DownloadProxyMessages.h"
40 #include "GamepadData.h"
41 #include "HighPerformanceGraphicsUsageSampler.h"
42 #include "LegacyCustomProtocolManagerMessages.h"
43 #include "LogInitialization.h"
44 #include "NetworkProcessCreationParameters.h"
45 #include "NetworkProcessMessages.h"
46 #include "NetworkProcessProxy.h"
47 #include "PerActivityStateCPUUsageSampler.h"
48 #include "SandboxExtension.h"
49 #include "StatisticsData.h"
50 #include "TextChecker.h"
51 #include "UIGamepad.h"
52 #include "UIGamepadProvider.h"
53 #include "WKContextPrivate.h"
54 #include "WebAutomationSession.h"
55 #include "WebCertificateInfo.h"
56 #include "WebContextSupplement.h"
57 #include "WebCookieManagerProxy.h"
58 #include "WebCoreArgumentCoders.h"
59 #include "WebGeolocationManagerProxy.h"
60 #include "WebKit2Initialize.h"
61 #include "WebMemorySampler.h"
62 #include "WebNotificationManagerProxy.h"
63 #include "WebPageGroup.h"
64 #include "WebPreferences.h"
65 #include "WebPreferencesKeys.h"
66 #include "WebProcessCreationParameters.h"
67 #include "WebProcessMessages.h"
68 #include "WebProcessPoolMessages.h"
69 #include "WebProcessProxy.h"
70 #include "WebsiteDataStore.h"
71 #include "WebsiteDataStoreParameters.h"
72 #include <WebCore/ApplicationCacheStorage.h>
73 #include <WebCore/Language.h>
74 #include <WebCore/LinkHash.h>
75 #include <WebCore/LogInitialization.h>
76 #include <WebCore/ResourceRequest.h>
77 #include <WebCore/SessionID.h>
78 #include <WebCore/URLParser.h>
79 #include <runtime/JSCInlines.h>
80 #include <wtf/CurrentTime.h>
81 #include <wtf/MainThread.h>
82 #include <wtf/NeverDestroyed.h>
83 #include <wtf/RunLoop.h>
84 #include <wtf/text/StringBuilder.h>
85
86 #if ENABLE(DATABASE_PROCESS)
87 #include "DatabaseProcessCreationParameters.h"
88 #include "DatabaseProcessMessages.h"
89 #endif
90
91 #if ENABLE(SERVICE_CONTROLS)
92 #include "ServicesController.h"
93 #endif
94
95 #if ENABLE(REMOTE_INSPECTOR)
96 #include <JavaScriptCore/RemoteInspector.h>
97 #endif
98
99 #if OS(LINUX)
100 #include "MemoryPressureMonitor.h"
101 #endif
102
103 #if PLATFORM(WAYLAND)
104 #include "WaylandCompositor.h"
105 #include <WebCore/PlatformDisplay.h>
106 #endif
107
108 #ifndef NDEBUG
109 #include <wtf/RefCountedLeakCounter.h>
110 #endif
111
112 using namespace WebCore;
113 using namespace WebKit;
114
115 namespace WebKit {
116
117 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, processPoolCounter, ("WebProcessPool"));
118
119 static uint64_t generateListenerIdentifier()
120 {
121     static uint64_t nextIdentifier = 1;
122     return nextIdentifier++;
123 }
124
125 static HashMap<uint64_t, Function<void(WebProcessPool&)>>& processPoolCreationListenerFunctionMap()
126 {
127     static NeverDestroyed<HashMap<uint64_t, Function<void(WebProcessPool&)>>> map;
128     return map;
129 }
130
131 uint64_t WebProcessPool::registerProcessPoolCreationListener(Function<void(WebProcessPool&)>&& function)
132 {
133     ASSERT(function);
134
135     auto identifier = generateListenerIdentifier();
136     processPoolCreationListenerFunctionMap().set(identifier, WTFMove(function));
137     return identifier;
138 }
139
140 void WebProcessPool::unregisterProcessPoolCreationListener(uint64_t identifier)
141 {
142     processPoolCreationListenerFunctionMap().remove(identifier);
143 }
144
145 Ref<WebProcessPool> WebProcessPool::create(API::ProcessPoolConfiguration& configuration)
146 {
147     InitializeWebKit2();
148     return adoptRef(*new WebProcessPool(configuration));
149 }
150
151 void WebProcessPool::notifyThisWebProcessPoolWasCreated()
152 {
153     auto& listenerMap = processPoolCreationListenerFunctionMap();
154
155     Vector<uint64_t> identifiers;
156     identifiers.reserveInitialCapacity(listenerMap.size());
157     for (auto identifier : listenerMap.keys())
158         identifiers.uncheckedAppend(identifier);
159
160     for (auto identifier : identifiers) {
161         auto iterator = listenerMap.find(identifier);
162         if (iterator == listenerMap.end())
163             continue;
164
165         // To make sure the Function object stays alive until after the function call has been made,
166         // we temporarily move it out of the map.
167         // This protects it from the Function calling unregisterProcessPoolCreationListener thereby
168         // removing itself from the map of listeners.
169         // If the identifier still exists in the map later, we move it back in.
170         Function<void(WebProcessPool&)> function = WTFMove(iterator->value);
171         function(*this);
172
173         iterator = listenerMap.find(identifier);
174         if (iterator != listenerMap.end()) {
175             ASSERT(!iterator->value);
176             iterator->value = WTFMove(function);
177         }
178     }
179 }
180
181 static Vector<WebProcessPool*>& processPools()
182 {
183     static NeverDestroyed<Vector<WebProcessPool*>> processPools;
184     return processPools;
185 }
186
187 const Vector<WebProcessPool*>& WebProcessPool::allProcessPools()
188 {
189     return processPools();
190 }
191
192 static WebsiteDataStore::Configuration legacyWebsiteDataStoreConfiguration(API::ProcessPoolConfiguration& processPoolConfiguration)
193 {
194     WebsiteDataStore::Configuration configuration;
195
196     configuration.localStorageDirectory = processPoolConfiguration.localStorageDirectory();
197     configuration.webSQLDatabaseDirectory = processPoolConfiguration.webSQLDatabaseDirectory();
198     configuration.applicationCacheDirectory = processPoolConfiguration.applicationCacheDirectory();
199     configuration.applicationCacheFlatFileSubdirectoryName = processPoolConfiguration.applicationCacheFlatFileSubdirectoryName();
200     configuration.mediaCacheDirectory = processPoolConfiguration.mediaCacheDirectory();
201     configuration.mediaKeysStorageDirectory = processPoolConfiguration.mediaKeysStorageDirectory();
202     configuration.resourceLoadStatisticsDirectory = processPoolConfiguration.resourceLoadStatisticsDirectory();
203     configuration.networkCacheDirectory = processPoolConfiguration.diskCacheDirectory();
204     configuration.javaScriptConfigurationDirectory = processPoolConfiguration.javaScriptConfigurationDirectory();
205
206     return configuration;
207 }
208
209 static HashSet<String, ASCIICaseInsensitiveHash>& globalURLSchemesWithCustomProtocolHandlers()
210 {
211     static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> set;
212     return set;
213 }
214
215 WebProcessPool::WebProcessPool(API::ProcessPoolConfiguration& configuration)
216     : m_configuration(configuration.copy())
217     , m_haveInitialEmptyProcess(false)
218     , m_processWithPageCache(0)
219     , m_defaultPageGroup(WebPageGroup::createNonNull())
220     , m_injectedBundleClient(std::make_unique<API::InjectedBundleClient>())
221     , m_automationClient(std::make_unique<API::AutomationClient>())
222     , m_downloadClient(std::make_unique<API::DownloadClient>())
223     , m_historyClient(std::make_unique<API::LegacyContextHistoryClient>())
224     , m_customProtocolManagerClient(std::make_unique<API::CustomProtocolManagerClient>())
225     , m_visitedLinkStore(VisitedLinkStore::create())
226     , m_visitedLinksPopulated(false)
227     , m_plugInAutoStartProvider(this)
228     , m_alwaysUsesComplexTextCodePath(false)
229     , m_shouldUseFontSmoothing(true)
230     , m_memorySamplerEnabled(false)
231     , m_memorySamplerInterval(1400.0)
232     , m_websiteDataStore(m_configuration->shouldHaveLegacyDataStore() ? API::WebsiteDataStore::createLegacy(legacyWebsiteDataStoreConfiguration(m_configuration)) : API::WebsiteDataStore::defaultDataStore())
233 #if PLATFORM(MAC)
234     , m_highPerformanceGraphicsUsageSampler(std::make_unique<HighPerformanceGraphicsUsageSampler>(*this))
235     , m_perActivityStateCPUUsageSampler(std::make_unique<PerActivityStateCPUUsageSampler>(*this))
236 #endif
237     , m_shouldUseTestingNetworkSession(false)
238     , m_processTerminationEnabled(true)
239     , m_canHandleHTTPSServerTrustEvaluation(true)
240     , m_didNetworkProcessCrash(false)
241     , m_memoryCacheDisabled(false)
242     , m_alwaysRunsAtBackgroundPriority(m_configuration->alwaysRunsAtBackgroundPriority())
243     , m_shouldTakeUIBackgroundAssertion(m_configuration->shouldTakeUIBackgroundAssertion())
244     , m_userObservablePageCounter([this](RefCounterEvent) { updateProcessSuppressionState(); })
245     , m_processSuppressionDisabledForPageCounter([this](RefCounterEvent) { updateProcessSuppressionState(); })
246     , m_hiddenPageThrottlingAutoIncreasesCounter([this](RefCounterEvent) { m_hiddenPageThrottlingTimer.startOneShot(0_s); })
247     , m_hiddenPageThrottlingTimer(RunLoop::main(), this, &WebProcessPool::updateHiddenPageThrottlingAutoIncreaseLimit)
248 {
249     for (auto& scheme : m_configuration->alwaysRevalidatedURLSchemes())
250         m_schemesToRegisterAsAlwaysRevalidated.add(scheme);
251
252     for (const auto& urlScheme : m_configuration->cachePartitionedURLSchemes())
253         m_schemesToRegisterAsCachePartitioned.add(urlScheme);
254
255     platformInitialize();
256
257     addMessageReceiver(Messages::WebProcessPool::messageReceiverName(), *this);
258
259     // NOTE: These sub-objects must be initialized after m_messageReceiverMap..
260     addSupplement<WebCookieManagerProxy>();
261     addSupplement<WebGeolocationManagerProxy>();
262     addSupplement<WebNotificationManagerProxy>();
263 #if ENABLE(MEDIA_SESSION)
264     addSupplement<WebMediaSessionFocusManager>();
265 #endif
266
267     processPools().append(this);
268
269     addLanguageChangeObserver(this, languageChanged);
270
271     resolvePathsForSandboxExtensions();
272
273 #if !LOG_DISABLED || !RELEASE_LOG_DISABLED
274     WebCore::initializeLogChannelsIfNecessary();
275     WebKit::initializeLogChannelsIfNecessary();
276 #endif // !LOG_DISABLED || !RELEASE_LOG_DISABLED
277
278 #ifndef NDEBUG
279     processPoolCounter.increment();
280 #endif
281
282     notifyThisWebProcessPoolWasCreated();
283 }
284
285 #if !PLATFORM(COCOA) && !PLATFORM(GTK) && !PLATFORM(WPE)
286 void WebProcessPool::platformInitialize()
287 {
288 }
289 #endif
290
291 WebProcessPool::~WebProcessPool()
292 {
293     bool removed = processPools().removeFirst(this);
294     ASSERT_UNUSED(removed, removed);
295
296     removeLanguageChangeObserver(this);
297
298     m_messageReceiverMap.invalidate();
299
300     for (auto& supplement : m_supplements.values()) {
301         supplement->processPoolDestroyed();
302         supplement->clearProcessPool();
303     }
304
305     invalidateCallbackMap(m_dictionaryCallbacks, CallbackBase::Error::OwnerWasInvalidated);
306
307     platformInvalidateContext();
308
309 #ifndef NDEBUG
310     processPoolCounter.decrement();
311 #endif
312
313     if (m_networkProcess)
314         m_networkProcess->shutDownProcess();
315
316 #if ENABLE(GAMEPAD)
317     if (!m_processesUsingGamepads.isEmpty())
318         UIGamepadProvider::singleton().processPoolStoppedUsingGamepads(*this);
319 #endif
320 }
321
322 void WebProcessPool::initializeClient(const WKContextClientBase* client)
323 {
324     m_client.initialize(client);
325 }
326
327 void WebProcessPool::setInjectedBundleClient(std::unique_ptr<API::InjectedBundleClient>&& client)
328 {
329     if (!client)
330         m_injectedBundleClient = std::make_unique<API::InjectedBundleClient>();
331     else
332         m_injectedBundleClient = WTFMove(client);
333 }
334
335 void WebProcessPool::initializeConnectionClient(const WKContextConnectionClientBase* client)
336 {
337     m_connectionClient.initialize(client);
338 }
339
340 void WebProcessPool::setHistoryClient(std::unique_ptr<API::LegacyContextHistoryClient>&& historyClient)
341 {
342     if (!historyClient)
343         m_historyClient = std::make_unique<API::LegacyContextHistoryClient>();
344     else
345         m_historyClient = WTFMove(historyClient);
346 }
347
348 void WebProcessPool::setDownloadClient(std::unique_ptr<API::DownloadClient>&& downloadClient)
349 {
350     if (!downloadClient)
351         m_downloadClient = std::make_unique<API::DownloadClient>();
352     else
353         m_downloadClient = WTFMove(downloadClient);
354 }
355
356 void WebProcessPool::setAutomationClient(std::unique_ptr<API::AutomationClient>&& automationClient)
357 {
358     if (!automationClient)
359         m_automationClient = std::make_unique<API::AutomationClient>();
360     else
361         m_automationClient = WTFMove(automationClient);
362 }
363
364 void WebProcessPool::setLegacyCustomProtocolManagerClient(std::unique_ptr<API::CustomProtocolManagerClient>&& customProtocolManagerClient)
365 {
366     if (!customProtocolManagerClient)
367         m_customProtocolManagerClient = std::make_unique<API::CustomProtocolManagerClient>();
368     else
369         m_customProtocolManagerClient = WTFMove(customProtocolManagerClient);
370 }
371
372 void WebProcessPool::setMaximumNumberOfProcesses(unsigned maximumNumberOfProcesses)
373 {
374     // Guard against API misuse.
375     if (!m_processes.isEmpty())
376         CRASH();
377
378     m_configuration->setMaximumProcessCount(maximumNumberOfProcesses);
379 }
380
381 IPC::Connection* WebProcessPool::networkingProcessConnection()
382 {
383     return m_networkProcess->connection();
384 }
385
386 void WebProcessPool::languageChanged(void* context)
387 {
388     static_cast<WebProcessPool*>(context)->languageChanged();
389 }
390
391 void WebProcessPool::languageChanged()
392 {
393     sendToAllProcesses(Messages::WebProcess::UserPreferredLanguagesChanged(userPreferredLanguages()));
394 #if USE(SOUP)
395     if (m_networkProcess)
396         m_networkProcess->send(Messages::NetworkProcess::UserPreferredLanguagesChanged(userPreferredLanguages()), 0);
397 #endif
398 }
399
400 void WebProcessPool::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
401 {
402     sendToAllProcesses(Messages::WebProcess::FullKeyboardAccessModeChanged(fullKeyboardAccessEnabled));
403 }
404
405 void WebProcessPool::textCheckerStateChanged()
406 {
407     sendToAllProcesses(Messages::WebProcess::SetTextCheckerState(TextChecker::state()));
408 }
409
410 NetworkProcessProxy& WebProcessPool::ensureNetworkProcess(WebsiteDataStore* withWebsiteDataStore)
411 {
412     if (m_networkProcess) {
413         if (withWebsiteDataStore)
414             m_networkProcess->send(Messages::NetworkProcess::AddWebsiteDataStore(withWebsiteDataStore->parameters()), 0);
415         return *m_networkProcess;
416     }
417
418     m_networkProcess = NetworkProcessProxy::create(*this);
419
420     NetworkProcessCreationParameters parameters;
421
422     parameters.privateBrowsingEnabled = WebPreferences::anyPagesAreUsingPrivateBrowsing();
423
424     parameters.cacheModel = cacheModel();
425     parameters.diskCacheSizeOverride = m_configuration->diskCacheSizeOverride();
426     parameters.canHandleHTTPSServerTrustEvaluation = m_canHandleHTTPSServerTrustEvaluation;
427
428     for (auto& scheme : globalURLSchemesWithCustomProtocolHandlers())
429         parameters.urlSchemesRegisteredForCustomProtocols.append(scheme);
430
431     for (auto& scheme : m_urlSchemesRegisteredForCustomProtocols)
432         parameters.urlSchemesRegisteredForCustomProtocols.append(scheme);
433
434     parameters.diskCacheDirectory = m_configuration->diskCacheDirectory();
435     if (!parameters.diskCacheDirectory.isEmpty())
436         SandboxExtension::createHandleForReadWriteDirectory(parameters.diskCacheDirectory, parameters.diskCacheDirectoryExtensionHandle);
437 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
438     parameters.shouldEnableNetworkCacheSpeculativeRevalidation = m_configuration->diskCacheSpeculativeValidationEnabled();
439 #endif
440
441 #if PLATFORM(IOS)
442     String cookieStorageDirectory = this->cookieStorageDirectory();
443     if (!cookieStorageDirectory.isEmpty())
444         SandboxExtension::createHandleForReadWriteDirectory(cookieStorageDirectory, parameters.cookieStorageDirectoryExtensionHandle);
445
446     String containerCachesDirectory = this->networkingCachesDirectory();
447     if (!containerCachesDirectory.isEmpty())
448         SandboxExtension::createHandleForReadWriteDirectory(containerCachesDirectory, parameters.containerCachesDirectoryExtensionHandle);
449
450     String parentBundleDirectory = this->parentBundleDirectory();
451     if (!parentBundleDirectory.isEmpty())
452         SandboxExtension::createHandle(parentBundleDirectory, SandboxExtension::ReadOnly, parameters.parentBundleDirectoryExtensionHandle);
453 #endif
454
455 #if OS(LINUX)
456     if (MemoryPressureMonitor::isEnabled())
457         parameters.memoryPressureMonitorHandle = MemoryPressureMonitor::singleton().createHandle();
458 #endif
459
460     parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession;
461     parameters.presentingApplicationPID = m_configuration->presentingApplicationPID();
462
463     // Add any platform specific parameters
464     platformInitializeNetworkProcess(parameters);
465
466     // Initialize the network process.
467     m_networkProcess->send(Messages::NetworkProcess::InitializeNetworkProcess(parameters), 0);
468
469 #if PLATFORM(COCOA)
470     m_networkProcess->send(Messages::NetworkProcess::SetQOS(networkProcessLatencyQOS(), networkProcessThroughputQOS()), 0);
471 #endif
472
473     if (m_didNetworkProcessCrash) {
474         m_didNetworkProcessCrash = false;
475         for (auto& process : m_processes)
476             process->reinstateNetworkProcessAssertionState(*m_networkProcess);
477         websiteDataStore().websiteDataStore().networkProcessDidCrash();
478     }
479
480     if (withWebsiteDataStore)
481         m_networkProcess->send(Messages::NetworkProcess::AddWebsiteDataStore(withWebsiteDataStore->parameters()), 0);
482
483     return *m_networkProcess;
484 }
485
486 void WebProcessPool::networkProcessCrashed(NetworkProcessProxy& networkProcessProxy, Vector<Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>>&& pendingReplies)
487 {
488     networkProcessFailedToLaunch(networkProcessProxy);
489     ASSERT(!m_networkProcess);
490     if (pendingReplies.isEmpty())
491         return;
492     auto& newNetworkProcess = ensureNetworkProcess();
493     for (auto& reply : pendingReplies)
494         newNetworkProcess.getNetworkProcessConnection(WTFMove(reply));
495 }
496
497 void WebProcessPool::networkProcessFailedToLaunch(NetworkProcessProxy& networkProcessProxy)
498 {
499     ASSERT(m_networkProcess);
500     ASSERT(&networkProcessProxy == m_networkProcess.get());
501     m_didNetworkProcessCrash = true;
502
503     for (auto& supplement : m_supplements.values())
504         supplement->processDidClose(&networkProcessProxy);
505
506     m_client.networkProcessDidCrash(this);
507
508     // Leave the process proxy around during client call, so that the client could query the process identifier.
509     m_networkProcess = nullptr;
510 }
511
512 void WebProcessPool::getNetworkProcessConnection(Ref<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>&& reply)
513 {
514     ensureNetworkProcess();
515     ASSERT(m_networkProcess);
516
517     m_networkProcess->getNetworkProcessConnection(WTFMove(reply));
518 }
519
520 #if ENABLE(DATABASE_PROCESS)
521 void WebProcessPool::ensureDatabaseProcessAndWebsiteDataStore(WebsiteDataStore* relevantDataStore)
522 {
523     // *********
524     // IMPORTANT: Do not change the directory structure for indexed databases on disk without first consulting a reviewer from Apple (<rdar://problem/17454712>)
525     // *********
526
527     if (!m_databaseProcess) {
528         m_databaseProcess = DatabaseProcessProxy::create(this);
529
530         DatabaseProcessCreationParameters parameters;
531 #if ENABLE(INDEXED_DATABASE)
532         ASSERT(!m_configuration->indexedDBDatabaseDirectory().isEmpty());
533
534         parameters.sessionID = websiteDataStore().websiteDataStore().sessionID();
535         parameters.indexedDatabaseDirectory = m_configuration->indexedDBDatabaseDirectory();
536         SandboxExtension::createHandleForReadWriteDirectory(parameters.indexedDatabaseDirectory, parameters.indexedDatabaseDirectoryExtensionHandle);
537 #endif
538
539         ASSERT(!parameters.indexedDatabaseDirectory.isEmpty());
540         m_databaseProcess->send(Messages::DatabaseProcess::InitializeWebsiteDataStore(parameters), 0);
541     }
542
543     if (!relevantDataStore || relevantDataStore == &websiteDataStore().websiteDataStore())
544         return;
545
546     m_databaseProcess->send(Messages::DatabaseProcess::InitializeWebsiteDataStore(relevantDataStore->databaseProcessParameters()), 0);
547 }
548
549 void WebProcessPool::getDatabaseProcessConnection(Ref<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>&& reply)
550 {
551     ensureDatabaseProcessAndWebsiteDataStore(nullptr);
552
553     m_databaseProcess->getDatabaseProcessConnection(WTFMove(reply));
554 }
555
556 void WebProcessPool::databaseProcessCrashed(DatabaseProcessProxy* databaseProcessProxy)
557 {
558     ASSERT(m_databaseProcess);
559     ASSERT(databaseProcessProxy == m_databaseProcess.get());
560
561     for (auto& supplement : m_supplements.values())
562         supplement->processDidClose(databaseProcessProxy);
563
564     m_client.databaseProcessDidCrash(this);
565     m_databaseProcess = nullptr;
566 }
567 #endif
568
569 void WebProcessPool::willStartUsingPrivateBrowsing()
570 {
571     for (auto* processPool : allProcessPools())
572         processPool->setAnyPageGroupMightHavePrivateBrowsingEnabled(true);
573 }
574
575 void WebProcessPool::willStopUsingPrivateBrowsing()
576 {
577     for (auto* processPool : allProcessPools())
578         processPool->setAnyPageGroupMightHavePrivateBrowsingEnabled(false);
579 }
580
581 void WebProcessPool::windowServerConnectionStateChanged()
582 {
583     size_t processCount = m_processes.size();
584     for (size_t i = 0; i < processCount; ++i)
585         m_processes[i]->windowServerConnectionStateChanged();
586 }
587
588 void WebProcessPool::setAnyPageGroupMightHavePrivateBrowsingEnabled(bool privateBrowsingEnabled)
589 {
590     if (networkProcess()) {
591         if (privateBrowsingEnabled)
592             networkProcess()->send(Messages::NetworkProcess::EnsurePrivateBrowsingSession({SessionID::legacyPrivateSessionID(), { }, { }, { }}), 0);
593         else
594             networkProcess()->send(Messages::NetworkProcess::DestroySession(SessionID::legacyPrivateSessionID()), 0);
595     }
596
597     if (privateBrowsingEnabled)
598         sendToAllProcesses(Messages::WebProcess::EnsurePrivateBrowsingSession(SessionID::legacyPrivateSessionID()));
599     else
600         sendToAllProcesses(Messages::WebProcess::DestroySession(SessionID::legacyPrivateSessionID()));
601 }
602
603 void (*s_invalidMessageCallback)(WKStringRef messageName);
604
605 void WebProcessPool::setInvalidMessageCallback(void (*invalidMessageCallback)(WKStringRef messageName))
606 {
607     s_invalidMessageCallback = invalidMessageCallback;
608 }
609
610 void WebProcessPool::didReceiveInvalidMessage(const IPC::StringReference& messageReceiverName, const IPC::StringReference& messageName)
611 {
612     if (!s_invalidMessageCallback)
613         return;
614
615     StringBuilder messageNameStringBuilder;
616     messageNameStringBuilder.append(messageReceiverName.data(), messageReceiverName.size());
617     messageNameStringBuilder.append('.');
618     messageNameStringBuilder.append(messageName.data(), messageName.size());
619
620     s_invalidMessageCallback(toAPI(API::String::create(messageNameStringBuilder.toString()).ptr()));
621 }
622
623 void WebProcessPool::processDidCachePage(WebProcessProxy* process)
624 {
625     if (m_processWithPageCache && m_processWithPageCache != process)
626         m_processWithPageCache->releasePageCache();
627     m_processWithPageCache = process;
628 }
629
630 void WebProcessPool::resolvePathsForSandboxExtensions()
631 {
632     m_resolvedPaths.injectedBundlePath = resolvePathForSandboxExtension(injectedBundlePath());
633     m_resolvedPaths.applicationCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->applicationCacheDirectory());
634     m_resolvedPaths.webSQLDatabaseDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->webSQLDatabaseDirectory());
635     m_resolvedPaths.mediaCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaCacheDirectory());
636     m_resolvedPaths.mediaKeyStorageDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaKeysStorageDirectory());
637     m_resolvedPaths.indexedDatabaseDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->indexedDBDatabaseDirectory());
638
639     m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.reserveCapacity(m_configuration->additionalReadAccessAllowedPaths().size());
640     for (const auto& path : m_configuration->additionalReadAccessAllowedPaths())
641         m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.uncheckedAppend(resolvePathForSandboxExtension(path.data()));
642
643     platformResolvePathsForSandboxExtensions();
644 }
645
646 WebProcessProxy& WebProcessPool::createNewWebProcess(WebsiteDataStore& websiteDataStore)
647 {
648     ensureNetworkProcess();
649
650     Ref<WebProcessProxy> process = WebProcessProxy::create(*this, websiteDataStore);
651
652     WebProcessCreationParameters parameters;
653
654     websiteDataStore.resolveDirectoriesIfNecessary();
655
656     parameters.injectedBundlePath = m_resolvedPaths.injectedBundlePath;
657     if (!parameters.injectedBundlePath.isEmpty())
658         SandboxExtension::createHandleWithoutResolvingPath(parameters.injectedBundlePath, SandboxExtension::ReadOnly, parameters.injectedBundlePathExtensionHandle);
659
660     parameters.additionalSandboxExtensionHandles.allocate(m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.size());
661     for (size_t i = 0, size = m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.size(); i < size; ++i)
662         SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.additionalWebProcessSandboxExtensionPaths[i], SandboxExtension::ReadOnly, parameters.additionalSandboxExtensionHandles[i]);
663
664     parameters.applicationCacheDirectory = websiteDataStore.resolvedApplicationCacheDirectory();
665     if (parameters.applicationCacheDirectory.isEmpty())
666         parameters.applicationCacheDirectory = m_resolvedPaths.applicationCacheDirectory;
667     if (!parameters.applicationCacheDirectory.isEmpty())
668         SandboxExtension::createHandleWithoutResolvingPath(parameters.applicationCacheDirectory, SandboxExtension::ReadWrite, parameters.applicationCacheDirectoryExtensionHandle);
669
670     parameters.applicationCacheFlatFileSubdirectoryName = m_configuration->applicationCacheFlatFileSubdirectoryName();
671
672     parameters.webSQLDatabaseDirectory = websiteDataStore.resolvedDatabaseDirectory();
673     if (parameters.webSQLDatabaseDirectory.isEmpty())
674         parameters.webSQLDatabaseDirectory = m_resolvedPaths.webSQLDatabaseDirectory;
675     if (!parameters.webSQLDatabaseDirectory.isEmpty())
676         SandboxExtension::createHandleWithoutResolvingPath(parameters.webSQLDatabaseDirectory, SandboxExtension::ReadWrite, parameters.webSQLDatabaseDirectoryExtensionHandle);
677
678     parameters.mediaCacheDirectory = websiteDataStore.resolvedMediaCacheDirectory();
679     if (parameters.mediaCacheDirectory.isEmpty())
680         parameters.mediaCacheDirectory = m_resolvedPaths.mediaCacheDirectory;
681     if (!parameters.mediaCacheDirectory.isEmpty())
682         SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaCacheDirectory, SandboxExtension::ReadWrite, parameters.mediaCacheDirectoryExtensionHandle);
683
684     parameters.mediaKeyStorageDirectory = websiteDataStore.resolvedMediaKeysDirectory();
685     if (parameters.mediaKeyStorageDirectory.isEmpty())
686         parameters.mediaKeyStorageDirectory = m_resolvedPaths.mediaKeyStorageDirectory;
687     if (!parameters.mediaKeyStorageDirectory.isEmpty())
688         SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaKeyStorageDirectory, SandboxExtension::ReadWrite, parameters.mediaKeyStorageDirectoryExtensionHandle);
689
690 #if PLATFORM(IOS)
691     setJavaScriptConfigurationFileEnabledFromDefaults();
692 #endif
693
694     if (javaScriptConfigurationFileEnabled()) {
695         parameters.javaScriptConfigurationDirectory = websiteDataStore.resolvedJavaScriptConfigurationDirectory();
696         if (!parameters.javaScriptConfigurationDirectory.isEmpty())
697             SandboxExtension::createHandleWithoutResolvingPath(parameters.javaScriptConfigurationDirectory, SandboxExtension::ReadWrite, parameters.javaScriptConfigurationDirectoryExtensionHandle);
698     }
699
700     parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession;
701
702     parameters.cacheModel = cacheModel();
703     parameters.languages = userPreferredLanguages();
704
705     copyToVector(m_schemesToRegisterAsEmptyDocument, parameters.urlSchemesRegisteredAsEmptyDocument);
706     copyToVector(m_schemesToRegisterAsSecure, parameters.urlSchemesRegisteredAsSecure);
707     copyToVector(m_schemesToRegisterAsBypassingContentSecurityPolicy, parameters.urlSchemesRegisteredAsBypassingContentSecurityPolicy);
708     copyToVector(m_schemesToSetDomainRelaxationForbiddenFor, parameters.urlSchemesForWhichDomainRelaxationIsForbidden);
709     copyToVector(m_schemesToRegisterAsLocal, parameters.urlSchemesRegisteredAsLocal);
710     copyToVector(m_schemesToRegisterAsNoAccess, parameters.urlSchemesRegisteredAsNoAccess);
711     copyToVector(m_schemesToRegisterAsDisplayIsolated, parameters.urlSchemesRegisteredAsDisplayIsolated);
712     copyToVector(m_schemesToRegisterAsCORSEnabled, parameters.urlSchemesRegisteredAsCORSEnabled);
713     copyToVector(m_schemesToRegisterAsAlwaysRevalidated, parameters.urlSchemesRegisteredAsAlwaysRevalidated);
714     copyToVector(m_schemesToRegisterAsCachePartitioned, parameters.urlSchemesRegisteredAsCachePartitioned);
715
716     parameters.shouldAlwaysUseComplexTextCodePath = m_alwaysUsesComplexTextCodePath;
717     parameters.shouldUseFontSmoothing = m_shouldUseFontSmoothing;
718
719     parameters.terminationTimeout = 0_s;
720
721     parameters.textCheckerState = TextChecker::state();
722
723     parameters.fullKeyboardAccessEnabled = WebProcessProxy::fullKeyboardAccessEnabled();
724
725     parameters.defaultRequestTimeoutInterval = API::URLRequest::defaultTimeoutInterval();
726
727 #if ENABLE(NOTIFICATIONS)
728     // FIXME: There should be a generic way for supplements to add to the intialization parameters.
729     parameters.notificationPermissions = supplement<WebNotificationManagerProxy>()->notificationPermissions();
730 #endif
731
732     parameters.plugInAutoStartOriginHashes = m_plugInAutoStartProvider.autoStartOriginHashesCopy();
733     copyToVector(m_plugInAutoStartProvider.autoStartOrigins(), parameters.plugInAutoStartOrigins);
734
735     parameters.memoryCacheDisabled = m_memoryCacheDisabled;
736
737 #if ENABLE(SERVICE_CONTROLS)
738     auto& serviceController = ServicesController::singleton();
739     parameters.hasImageServices = serviceController.hasImageServices();
740     parameters.hasSelectionServices = serviceController.hasSelectionServices();
741     parameters.hasRichContentServices = serviceController.hasRichContentServices();
742     serviceController.refreshExistingServices();
743 #endif
744
745 #if ENABLE(NETSCAPE_PLUGIN_API)
746     parameters.pluginLoadClientPolicies = m_pluginLoadClientPolicies;
747 #endif
748
749 #if OS(LINUX)
750     parameters.shouldEnableMemoryPressureReliefLogging = true;
751     if (MemoryPressureMonitor::isEnabled())
752         parameters.memoryPressureMonitorHandle = MemoryPressureMonitor::singleton().createHandle();
753 #endif
754
755 #if PLATFORM(WAYLAND) && USE(EGL)
756     if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland)
757         parameters.waylandCompositorDisplayName = WaylandCompositor::singleton().displayName();
758 #endif
759
760     parameters.resourceLoadStatisticsEnabled = resourceLoadStatisticsEnabled();
761 #if ENABLE(MEDIA_STREAM)
762     parameters.shouldCaptureAudioInUIProcess = m_configuration->shouldCaptureAudioInUIProcess();
763 #endif
764
765     parameters.presentingApplicationPID = m_configuration->presentingApplicationPID();
766
767     // Add any platform specific parameters
768     platformInitializeWebProcess(parameters);
769
770     RefPtr<API::Object> injectedBundleInitializationUserData = m_injectedBundleClient->getInjectedBundleInitializationUserData(*this);
771     if (!injectedBundleInitializationUserData)
772         injectedBundleInitializationUserData = m_injectedBundleInitializationUserData;
773     parameters.initializationUserData = UserData(process->transformObjectsToHandles(injectedBundleInitializationUserData.get()));
774
775     process->send(Messages::WebProcess::InitializeWebProcess(parameters), 0);
776
777 #if PLATFORM(COCOA)
778     process->send(Messages::WebProcess::SetQOS(webProcessLatencyQOS(), webProcessThroughputQOS()), 0);
779 #endif
780
781     if (WebPreferences::anyPagesAreUsingPrivateBrowsing())
782         process->send(Messages::WebProcess::EnsurePrivateBrowsingSession(SessionID::legacyPrivateSessionID()), 0);
783
784     if (m_automationSession)
785         process->send(Messages::WebProcess::EnsureAutomationSessionProxy(m_automationSession->sessionIdentifier()), 0);
786
787     m_processes.append(process.ptr());
788
789     ASSERT(m_messagesToInjectedBundlePostedToEmptyContext.isEmpty());
790
791 #if ENABLE(REMOTE_INSPECTOR)
792     // Initialize remote inspector connection now that we have a sub-process that is hosting one of our web views.
793     Inspector::RemoteInspector::singleton(); 
794 #endif
795
796     return process;
797 }
798
799 void WebProcessPool::warmInitialProcess()  
800 {
801     if (m_haveInitialEmptyProcess) {
802         ASSERT(!m_processes.isEmpty());
803         return;
804     }
805
806     if (m_processes.size() >= maximumNumberOfProcesses())
807         return;
808
809     createNewWebProcess(m_websiteDataStore->websiteDataStore());
810     m_haveInitialEmptyProcess = true;
811 }
812
813 void WebProcessPool::enableProcessTermination()
814 {
815     m_processTerminationEnabled = true;
816     Vector<RefPtr<WebProcessProxy>> processes = m_processes;
817     for (size_t i = 0; i < processes.size(); ++i) {
818         if (shouldTerminate(processes[i].get()))
819             processes[i]->terminate();
820     }
821 }
822
823 bool WebProcessPool::shouldTerminate(WebProcessProxy* process)
824 {
825     ASSERT(m_processes.contains(process));
826
827     if (!m_processTerminationEnabled)
828         return false;
829
830     return true;
831 }
832
833 void WebProcessPool::processDidFinishLaunching(WebProcessProxy* process)
834 {
835     ASSERT(m_processes.contains(process));
836
837     if (!m_visitedLinksPopulated) {
838         populateVisitedLinks();
839         m_visitedLinksPopulated = true;
840     }
841
842     // Sometimes the memorySampler gets initialized after process initialization has happened but before the process has finished launching
843     // so check if it needs to be started here
844     if (m_memorySamplerEnabled) {
845         SandboxExtension::Handle sampleLogSandboxHandle;        
846         double now = WTF::currentTime();
847         String sampleLogFilePath = String::format("WebProcess%llupid%d", static_cast<unsigned long long>(now), process->processIdentifier());
848         sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::ReadWrite, sampleLogSandboxHandle);
849         
850         process->send(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, m_memorySamplerInterval), 0);
851     }
852
853     if (m_configuration->fullySynchronousModeIsAllowedForTesting())
854         process->connection()->allowFullySynchronousModeForTesting();
855
856     if (m_configuration->ignoreSynchronousMessagingTimeoutsForTesting())
857         process->connection()->ignoreTimeoutsForTesting();
858
859     m_connectionClient.didCreateConnection(this, process->webConnection());
860 }
861
862 void WebProcessPool::disconnectProcess(WebProcessProxy* process)
863 {
864     ASSERT(m_processes.contains(process));
865
866     if (m_haveInitialEmptyProcess && process == m_processes.last())
867         m_haveInitialEmptyProcess = false;
868
869     // FIXME (Multi-WebProcess): <rdar://problem/12239765> Some of the invalidation calls of the other supplements are still necessary in multi-process mode, but they should only affect data structures pertaining to the process being disconnected.
870     // Clearing everything causes assertion failures, so it's less trouble to skip that for now.
871     RefPtr<WebProcessProxy> protect(process);
872     if (m_processWithPageCache == process)
873         m_processWithPageCache = nullptr;
874
875     static_cast<WebContextSupplement*>(supplement<WebGeolocationManagerProxy>())->processDidClose(process);
876
877     m_processes.removeFirst(process);
878
879 #if ENABLE(GAMEPAD)
880     if (m_processesUsingGamepads.contains(process))
881         processStoppedUsingGamepads(*process);
882 #endif
883 }
884
885 WebProcessProxy& WebProcessPool::createNewWebProcessRespectingProcessCountLimit(WebsiteDataStore& websiteDataStore)
886 {
887     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=168676
888     // Once WebsiteDataStores are truly per-view instead of per-process, remove this nonsense.
889
890 #if PLATFORM(COCOA)
891     bool mustMatchDataStore = &websiteDataStore != &API::WebsiteDataStore::defaultDataStore()->websiteDataStore();
892 #else
893     bool mustMatchDataStore = false;
894 #endif
895
896     if (m_processes.size() < maximumNumberOfProcesses())
897         return createNewWebProcess(websiteDataStore);
898
899     Vector<RefPtr<WebProcessProxy>> processesMatchingDataStore;
900     if (mustMatchDataStore) {
901         for (auto& process : m_processes) {
902             if (&process->websiteDataStore() == &websiteDataStore)
903                 processesMatchingDataStore.append(process);
904         }
905
906         if (processesMatchingDataStore.isEmpty())
907             return createNewWebProcess(websiteDataStore);
908     }
909
910     // Choose the process with fewest pages.
911     auto* processes = mustMatchDataStore ? &processesMatchingDataStore : &m_processes;
912     ASSERT(!processes->isEmpty());
913     auto& process = *std::min_element(processes->begin(), processes->end(), [](const RefPtr<WebProcessProxy>& a, const RefPtr<WebProcessProxy>& b) {
914         return a->pageCount() < b->pageCount();
915     });
916
917     return *process;
918 }
919
920 Ref<WebPageProxy> WebProcessPool::createWebPage(PageClient& pageClient, Ref<API::PageConfiguration>&& pageConfiguration)
921 {
922     if (!pageConfiguration->pageGroup())
923         pageConfiguration->setPageGroup(m_defaultPageGroup.ptr());
924     if (!pageConfiguration->preferences())
925         pageConfiguration->setPreferences(&pageConfiguration->pageGroup()->preferences());
926     if (!pageConfiguration->userContentController())
927         pageConfiguration->setUserContentController(&pageConfiguration->pageGroup()->userContentController());
928     if (!pageConfiguration->visitedLinkStore())
929         pageConfiguration->setVisitedLinkStore(m_visitedLinkStore.ptr());
930
931     if (!pageConfiguration->websiteDataStore()) {
932         ASSERT(!pageConfiguration->sessionID().isValid());
933         pageConfiguration->setWebsiteDataStore(m_websiteDataStore.ptr());
934         pageConfiguration->setSessionID(pageConfiguration->preferences()->privateBrowsingEnabled() ? SessionID::legacyPrivateSessionID() : m_websiteDataStore->websiteDataStore().sessionID());
935     }
936
937     RefPtr<WebProcessProxy> process;
938     if (m_haveInitialEmptyProcess) {
939         process = m_processes.last();
940         m_haveInitialEmptyProcess = false;
941     } else if (pageConfiguration->relatedPage()) {
942         // Sharing processes, e.g. when creating the page via window.open().
943         process = &pageConfiguration->relatedPage()->process();
944     } else
945         process = &createNewWebProcessRespectingProcessCountLimit(pageConfiguration->websiteDataStore()->websiteDataStore());
946
947     return process->createWebPage(pageClient, WTFMove(pageConfiguration));
948 }
949
950 void WebProcessPool::pageAddedToProcess(WebPageProxy& page)
951 {
952     auto result = m_sessionToPagesMap.add(page.sessionID(), HashSet<WebPageProxy*>()).iterator->value.add(&page);
953     ASSERT_UNUSED(result, result.isNewEntry);
954
955     auto sessionID = page.sessionID();
956     if (sessionID.isEphemeral()) {
957         // FIXME: Merge NetworkProcess::EnsurePrivateBrowsingSession and NetworkProcess::AddWebsiteDataStore into one message type.
958         // They do basically the same thing.
959         ASSERT(page.websiteDataStore().parameters().sessionID == sessionID);
960         sendToNetworkingProcess(Messages::NetworkProcess::EnsurePrivateBrowsingSession(page.websiteDataStore().parameters()));
961         page.process().send(Messages::WebProcess::EnsurePrivateBrowsingSession(sessionID), 0);
962     } else if (sessionID != SessionID::defaultSessionID()) {
963         sendToNetworkingProcess(Messages::NetworkProcess::AddWebsiteDataStore(page.websiteDataStore().parameters()));
964         page.process().send(Messages::WebProcess::AddWebsiteDataStore(page.websiteDataStore().parameters()), 0);
965
966 #if ENABLE(INDEXED_DATABASE)
967         auto databaseParameters = page.websiteDataStore().databaseProcessParameters();
968         if (!databaseParameters.indexedDatabaseDirectory.isEmpty())
969             sendToDatabaseProcessRelaunchingIfNecessary(Messages::DatabaseProcess::InitializeWebsiteDataStore(databaseParameters));
970 #endif
971     }
972 }
973
974 void WebProcessPool::pageRemovedFromProcess(WebPageProxy& page)
975 {
976     auto sessionID = page.sessionID();
977     auto iterator = m_sessionToPagesMap.find(sessionID);
978     ASSERT(iterator != m_sessionToPagesMap.end());
979
980     auto takenPage = iterator->value.take(&page);
981     ASSERT_UNUSED(takenPage, takenPage == &page);
982
983     if (iterator->value.isEmpty()) {
984         m_sessionToPagesMap.remove(iterator);
985
986         if (sessionID == SessionID::defaultSessionID())
987             return;
988
989         // The last user of this non-default SessionID is gone, so clean it up in the child processes.
990         if (networkProcess())
991             networkProcess()->send(Messages::NetworkProcess::DestroySession(sessionID), 0);
992         page.process().send(Messages::WebProcess::DestroySession(sessionID), 0);
993     }
994 }
995
996 DownloadProxy* WebProcessPool::download(WebPageProxy* initiatingPage, const ResourceRequest& request, const String& suggestedFilename)
997 {
998     DownloadProxy* downloadProxy = createDownloadProxy(request);
999     SessionID sessionID = initiatingPage ? initiatingPage->sessionID() : SessionID::defaultSessionID();
1000
1001     if (initiatingPage)
1002         initiatingPage->handleDownloadRequest(downloadProxy);
1003
1004     if (networkProcess()) {
1005         ResourceRequest updatedRequest(request);
1006         // Request's firstPartyForCookies will be used as Original URL of the download request.
1007         // We set the value to top level document's URL.
1008         if (initiatingPage)
1009             updatedRequest.setFirstPartyForCookies(URL(URL(), initiatingPage->pageLoadState().url()));
1010         else
1011             updatedRequest.setFirstPartyForCookies(URL());
1012         networkProcess()->send(Messages::NetworkProcess::DownloadRequest(sessionID, downloadProxy->downloadID(), updatedRequest, suggestedFilename), 0);
1013         return downloadProxy;
1014     }
1015
1016     return downloadProxy;
1017 }
1018
1019 DownloadProxy* WebProcessPool::resumeDownload(const API::Data* resumeData, const String& path)
1020 {
1021     DownloadProxy* downloadProxy = createDownloadProxy(ResourceRequest());
1022
1023     SandboxExtension::Handle sandboxExtensionHandle;
1024     if (!path.isEmpty())
1025         SandboxExtension::createHandle(path, SandboxExtension::ReadWrite, sandboxExtensionHandle);
1026
1027     if (networkProcess()) {
1028         // FIXME: If we started a download in an ephemeral session and that session still exists, we should find a way to use that same session.
1029         networkProcess()->send(Messages::NetworkProcess::ResumeDownload(SessionID::defaultSessionID(), downloadProxy->downloadID(), resumeData->dataReference(), path, sandboxExtensionHandle), 0);
1030         return downloadProxy;
1031     }
1032
1033     return downloadProxy;
1034 }
1035
1036 void WebProcessPool::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody)
1037 {
1038     for (auto& process : m_processes) {
1039         // FIXME: Return early if the message body contains any references to WKPageRefs/WKFrameRefs etc. since they're local to a process.
1040         process->send(Messages::WebProcess::HandleInjectedBundleMessage(messageName, UserData(process->transformObjectsToHandles(messageBody).get())), 0);
1041     }
1042 }
1043
1044 void WebProcessPool::populateVisitedLinks()
1045 {
1046     m_historyClient->populateVisitedLinks(*this);
1047 }
1048
1049 WebProcessPool::Statistics& WebProcessPool::statistics()
1050 {
1051     static Statistics statistics = Statistics();
1052
1053     return statistics;
1054 }
1055
1056 #if ENABLE(NETSCAPE_PLUGIN_API)
1057 void WebProcessPool::setAdditionalPluginsDirectory(const String& directory)
1058 {
1059     Vector<String> directories;
1060     directories.append(directory);
1061
1062     m_pluginInfoStore.setAdditionalPluginsDirectories(directories);
1063 }
1064
1065 void WebProcessPool::refreshPlugins()
1066 {
1067     m_pluginInfoStore.refresh();
1068     sendToAllProcesses(Messages::WebProcess::RefreshPlugins());
1069 }
1070
1071 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1072
1073 pid_t WebProcessPool::networkProcessIdentifier()
1074 {
1075     if (!m_networkProcess)
1076         return 0;
1077
1078     return m_networkProcess->processIdentifier();
1079 }
1080
1081 pid_t WebProcessPool::databaseProcessIdentifier()
1082 {
1083 #if ENABLE(DATABASE_PROCESS)
1084     if (!m_databaseProcess)
1085         return 0;
1086
1087     return m_databaseProcess->processIdentifier();
1088 #else
1089     return 0;
1090 #endif
1091 }
1092
1093 void WebProcessPool::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
1094 {
1095     m_alwaysUsesComplexTextCodePath = alwaysUseComplexText;
1096     sendToAllProcesses(Messages::WebProcess::SetAlwaysUsesComplexTextCodePath(alwaysUseComplexText));
1097 }
1098
1099 void WebProcessPool::setShouldUseFontSmoothing(bool useFontSmoothing)
1100 {
1101     m_shouldUseFontSmoothing = useFontSmoothing;
1102     sendToAllProcesses(Messages::WebProcess::SetShouldUseFontSmoothing(useFontSmoothing));
1103 }
1104
1105 void WebProcessPool::setResourceLoadStatisticsEnabled(bool enabled)
1106 {
1107     m_resourceLoadStatisticsEnabled = enabled;
1108     sendToAllProcesses(Messages::WebProcess::SetResourceLoadStatisticsEnabled(enabled));
1109 }
1110
1111 void WebProcessPool::registerURLSchemeAsEmptyDocument(const String& urlScheme)
1112 {
1113     m_schemesToRegisterAsEmptyDocument.add(urlScheme);
1114     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsEmptyDocument(urlScheme));
1115 }
1116
1117 void WebProcessPool::registerURLSchemeAsSecure(const String& urlScheme)
1118 {
1119     m_schemesToRegisterAsSecure.add(urlScheme);
1120     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsSecure(urlScheme));
1121 }
1122
1123 void WebProcessPool::registerURLSchemeAsBypassingContentSecurityPolicy(const String& urlScheme)
1124 {
1125     m_schemesToRegisterAsBypassingContentSecurityPolicy.add(urlScheme);
1126     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsBypassingContentSecurityPolicy(urlScheme));
1127 }
1128
1129 void WebProcessPool::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme)
1130 {
1131     m_schemesToSetDomainRelaxationForbiddenFor.add(urlScheme);
1132     sendToAllProcesses(Messages::WebProcess::SetDomainRelaxationForbiddenForURLScheme(urlScheme));
1133 }
1134
1135 void WebProcessPool::setCanHandleHTTPSServerTrustEvaluation(bool value)
1136 {
1137     m_canHandleHTTPSServerTrustEvaluation = value;
1138     if (m_networkProcess) {
1139         m_networkProcess->send(Messages::NetworkProcess::SetCanHandleHTTPSServerTrustEvaluation(value), 0);
1140         return;
1141     }
1142 }
1143
1144 void WebProcessPool::registerURLSchemeAsLocal(const String& urlScheme)
1145 {
1146     m_schemesToRegisterAsLocal.add(urlScheme);
1147     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsLocal(urlScheme));
1148 }
1149
1150 void WebProcessPool::registerURLSchemeAsNoAccess(const String& urlScheme)
1151 {
1152     m_schemesToRegisterAsNoAccess.add(urlScheme);
1153     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsNoAccess(urlScheme));
1154 }
1155
1156 void WebProcessPool::registerURLSchemeAsDisplayIsolated(const String& urlScheme)
1157 {
1158     m_schemesToRegisterAsDisplayIsolated.add(urlScheme);
1159     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsDisplayIsolated(urlScheme));
1160 }
1161
1162 void WebProcessPool::registerURLSchemeAsCORSEnabled(const String& urlScheme)
1163 {
1164     m_schemesToRegisterAsCORSEnabled.add(urlScheme);
1165     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsCORSEnabled(urlScheme));
1166 }
1167
1168 void WebProcessPool::registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme)
1169 {
1170     if (!urlScheme)
1171         return;
1172
1173     globalURLSchemesWithCustomProtocolHandlers().add(urlScheme);
1174     for (auto* processPool : allProcessPools())
1175         processPool->registerSchemeForCustomProtocol(urlScheme);
1176 }
1177
1178 void WebProcessPool::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme)
1179 {
1180     if (!urlScheme)
1181         return;
1182
1183     globalURLSchemesWithCustomProtocolHandlers().remove(urlScheme);
1184     for (auto* processPool : allProcessPools())
1185         processPool->unregisterSchemeForCustomProtocol(urlScheme);
1186 }
1187
1188 void WebProcessPool::registerURLSchemeAsCachePartitioned(const String& urlScheme)
1189 {
1190     m_schemesToRegisterAsCachePartitioned.add(urlScheme);
1191     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsCachePartitioned(urlScheme));
1192 }
1193
1194 void WebProcessPool::setCacheModel(CacheModel cacheModel)
1195 {
1196     m_configuration->setCacheModel(cacheModel);
1197     sendToAllProcesses(Messages::WebProcess::SetCacheModel(cacheModel));
1198
1199     if (m_networkProcess)
1200         m_networkProcess->send(Messages::NetworkProcess::SetCacheModel(cacheModel), 0);
1201 }
1202
1203 void WebProcessPool::setDefaultRequestTimeoutInterval(double timeoutInterval)
1204 {
1205     sendToAllProcesses(Messages::WebProcess::SetDefaultRequestTimeoutInterval(timeoutInterval));
1206 }
1207
1208 DownloadProxy* WebProcessPool::createDownloadProxy(const ResourceRequest& request)
1209 {
1210     return ensureNetworkProcess().createDownloadProxy(request);
1211 }
1212
1213 void WebProcessPool::addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver& messageReceiver)
1214 {
1215     m_messageReceiverMap.addMessageReceiver(messageReceiverName, messageReceiver);
1216 }
1217
1218 void WebProcessPool::addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver& messageReceiver)
1219 {
1220     m_messageReceiverMap.addMessageReceiver(messageReceiverName, destinationID, messageReceiver);
1221 }
1222
1223 void WebProcessPool::removeMessageReceiver(IPC::StringReference messageReceiverName)
1224 {
1225     m_messageReceiverMap.removeMessageReceiver(messageReceiverName);
1226 }
1227
1228 void WebProcessPool::removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID)
1229 {
1230     m_messageReceiverMap.removeMessageReceiver(messageReceiverName, destinationID);
1231 }
1232
1233 bool WebProcessPool::dispatchMessage(IPC::Connection& connection, IPC::Decoder& decoder)
1234 {
1235     return m_messageReceiverMap.dispatchMessage(connection, decoder);
1236 }
1237
1238 bool WebProcessPool::dispatchSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
1239 {
1240     return m_messageReceiverMap.dispatchSyncMessage(connection, decoder, replyEncoder);
1241 }
1242
1243 void WebProcessPool::setEnhancedAccessibility(bool flag)
1244 {
1245     sendToAllProcesses(Messages::WebProcess::SetEnhancedAccessibility(flag));
1246 }
1247     
1248 void WebProcessPool::startMemorySampler(const double interval)
1249 {    
1250     // For new WebProcesses we will also want to start the Memory Sampler
1251     m_memorySamplerEnabled = true;
1252     m_memorySamplerInterval = interval;
1253     
1254     // For UIProcess
1255 #if ENABLE(MEMORY_SAMPLER)
1256     WebMemorySampler::singleton()->start(interval);
1257 #endif
1258     
1259     // For WebProcess
1260     SandboxExtension::Handle sampleLogSandboxHandle;    
1261     double now = WTF::currentTime();
1262     String sampleLogFilePath = String::format("WebProcess%llu", static_cast<unsigned long long>(now));
1263     sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::ReadWrite, sampleLogSandboxHandle);
1264     
1265     sendToAllProcesses(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, interval));
1266 }
1267
1268 void WebProcessPool::stopMemorySampler()
1269 {    
1270     // For WebProcess
1271     m_memorySamplerEnabled = false;
1272     
1273     // For UIProcess
1274 #if ENABLE(MEMORY_SAMPLER)
1275     WebMemorySampler::singleton()->stop();
1276 #endif
1277
1278     sendToAllProcesses(Messages::WebProcess::StopMemorySampler());
1279 }
1280
1281 void WebProcessPool::useTestingNetworkSession()
1282 {
1283     ASSERT(m_processes.isEmpty());
1284     ASSERT(!m_networkProcess);
1285
1286     if (m_networkProcess)
1287         return;
1288
1289     if (!m_processes.isEmpty())
1290         return;
1291
1292     m_shouldUseTestingNetworkSession = true;
1293 }
1294
1295 template<typename T, typename U>
1296 void WebProcessPool::sendSyncToNetworkingProcess(T&& message, U&& reply)
1297 {
1298     if (m_networkProcess && m_networkProcess->canSendMessage())
1299         m_networkProcess->sendSync(std::forward<T>(message), std::forward<U>(reply), 0);
1300 }
1301
1302 void WebProcessPool::setAllowsAnySSLCertificateForWebSocket(bool allows)
1303 {
1304     sendSyncToNetworkingProcess(Messages::NetworkProcess::SetAllowsAnySSLCertificateForWebSocket(allows), Messages::NetworkProcess::SetAllowsAnySSLCertificateForWebSocket::Reply());
1305 }
1306
1307 void WebProcessPool::clearCachedCredentials()
1308 {
1309     sendToAllProcesses(Messages::WebProcess::ClearCachedCredentials());
1310     if (m_networkProcess)
1311         m_networkProcess->send(Messages::NetworkProcess::ClearCachedCredentials(), 0);
1312 }
1313
1314 void WebProcessPool::terminateDatabaseProcess()
1315 {
1316 #if ENABLE(DATABASE_PROCESS)
1317     if (!m_databaseProcess)
1318         return;
1319
1320     m_databaseProcess->terminate();
1321     m_databaseProcess = nullptr;
1322 #endif
1323 }
1324
1325 void WebProcessPool::terminateNetworkProcess()
1326 {
1327     if (!m_networkProcess)
1328         return;
1329     
1330     m_networkProcess->terminate();
1331     m_networkProcess = nullptr;
1332     m_didNetworkProcessCrash = true;
1333 }
1334
1335 void WebProcessPool::syncNetworkProcessCookies()
1336 {
1337     sendSyncToNetworkingProcess(Messages::NetworkProcess::SyncAllCookies(), Messages::NetworkProcess::SyncAllCookies::Reply());
1338 }
1339
1340 void WebProcessPool::allowSpecificHTTPSCertificateForHost(const WebCertificateInfo* certificate, const String& host)
1341 {
1342     ensureNetworkProcess();
1343     m_networkProcess->send(Messages::NetworkProcess::AllowSpecificHTTPSCertificateForHost(certificate->certificateInfo(), host), 0);
1344 }
1345
1346 void WebProcessPool::updateAutomationCapabilities() const
1347 {
1348 #if ENABLE(REMOTE_INSPECTOR)
1349     Inspector::RemoteInspector::singleton().clientCapabilitiesDidChange();
1350 #endif
1351 }
1352
1353 void WebProcessPool::setAutomationSession(RefPtr<WebAutomationSession>&& automationSession)
1354 {
1355     m_automationSession = WTFMove(automationSession);
1356
1357 #if ENABLE(REMOTE_INSPECTOR)
1358     if (m_automationSession) {
1359         m_automationSession->init();
1360         m_automationSession->setProcessPool(this);
1361
1362         sendToAllProcesses(Messages::WebProcess::EnsureAutomationSessionProxy(m_automationSession->sessionIdentifier()));
1363     } else
1364         sendToAllProcesses(Messages::WebProcess::DestroyAutomationSessionProxy());
1365 #endif
1366 }
1367
1368 void WebProcessPool::setHTTPPipeliningEnabled(bool enabled)
1369 {
1370 #if PLATFORM(COCOA)
1371     ResourceRequest::setHTTPPipeliningEnabled(enabled);
1372 #else
1373     UNUSED_PARAM(enabled);
1374 #endif
1375 }
1376
1377 bool WebProcessPool::httpPipeliningEnabled() const
1378 {
1379 #if PLATFORM(COCOA)
1380     return ResourceRequest::httpPipeliningEnabled();
1381 #else
1382     return false;
1383 #endif
1384 }
1385
1386 void WebProcessPool::getStatistics(uint32_t statisticsMask, Function<void (API::Dictionary*, CallbackBase::Error)>&& callbackFunction)
1387 {
1388     if (!statisticsMask) {
1389         callbackFunction(nullptr, CallbackBase::Error::Unknown);
1390         return;
1391     }
1392
1393     RefPtr<StatisticsRequest> request = StatisticsRequest::create(DictionaryCallback::create(WTFMove(callbackFunction)));
1394
1395     if (statisticsMask & StatisticsRequestTypeWebContent)
1396         requestWebContentStatistics(request.get());
1397     
1398     if (statisticsMask & StatisticsRequestTypeNetworking)
1399         requestNetworkingStatistics(request.get());
1400 }
1401
1402 void WebProcessPool::requestWebContentStatistics(StatisticsRequest* request)
1403 {
1404     // FIXME (Multi-WebProcess) <rdar://problem/13200059>: Make getting statistics from multiple WebProcesses work.
1405 }
1406
1407 void WebProcessPool::requestNetworkingStatistics(StatisticsRequest* request)
1408 {
1409     if (!m_networkProcess) {
1410         LOG_ERROR("Attempt to get NetworkProcess statistics but the NetworkProcess is unavailable");
1411         return;
1412     }
1413
1414     uint64_t requestID = request->addOutstandingRequest();
1415     m_statisticsRequests.set(requestID, request);
1416     m_networkProcess->send(Messages::NetworkProcess::GetNetworkProcessStatistics(requestID), 0);
1417 }
1418
1419 static WebProcessProxy* webProcessProxyFromConnection(IPC::Connection& connection, const Vector<RefPtr<WebProcessProxy>>& processes)
1420 {
1421     for (auto& process : processes) {
1422         if (process->hasConnection(connection))
1423             return process.get();
1424     }
1425
1426     ASSERT_NOT_REACHED();
1427     return nullptr;
1428 }
1429
1430 void WebProcessPool::handleMessage(IPC::Connection& connection, const String& messageName, const WebKit::UserData& messageBody)
1431 {
1432     auto* webProcessProxy = webProcessProxyFromConnection(connection, m_processes);
1433     if (!webProcessProxy)
1434         return;
1435     m_injectedBundleClient->didReceiveMessageFromInjectedBundle(*this, messageName, webProcessProxy->transformHandlesToObjects(messageBody.object()).get());
1436 }
1437
1438 void WebProcessPool::handleSynchronousMessage(IPC::Connection& connection, const String& messageName, const UserData& messageBody, UserData& returnUserData)
1439 {
1440     auto* webProcessProxy = webProcessProxyFromConnection(connection, m_processes);
1441     if (!webProcessProxy)
1442         return;
1443
1444     RefPtr<API::Object> returnData;
1445     m_injectedBundleClient->didReceiveSynchronousMessageFromInjectedBundle(*this, messageName, webProcessProxy->transformHandlesToObjects(messageBody.object()).get(), returnData);
1446     returnUserData = UserData(webProcessProxy->transformObjectsToHandles(returnData.get()));
1447 }
1448
1449 void WebProcessPool::didGetStatistics(const StatisticsData& statisticsData, uint64_t requestID)
1450 {
1451     RefPtr<StatisticsRequest> request = m_statisticsRequests.take(requestID);
1452     if (!request) {
1453         LOG_ERROR("Cannot report networking statistics.");
1454         return;
1455     }
1456
1457     request->completedRequest(requestID, statisticsData);
1458 }
1459
1460 #if ENABLE(GAMEPAD)
1461
1462 void WebProcessPool::startedUsingGamepads(IPC::Connection& connection)
1463 {
1464     auto* proxy = webProcessProxyFromConnection(connection, m_processes);
1465     if (!proxy)
1466         return;
1467
1468     bool wereAnyProcessesUsingGamepads = !m_processesUsingGamepads.isEmpty();
1469
1470     ASSERT(!m_processesUsingGamepads.contains(proxy));
1471     m_processesUsingGamepads.add(proxy);
1472
1473     if (!wereAnyProcessesUsingGamepads)
1474         UIGamepadProvider::singleton().processPoolStartedUsingGamepads(*this);
1475
1476     proxy->send(Messages::WebProcess::SetInitialGamepads(UIGamepadProvider::singleton().snapshotGamepads()), 0);
1477 }
1478
1479 void WebProcessPool::stoppedUsingGamepads(IPC::Connection& connection)
1480 {
1481     auto* proxy = webProcessProxyFromConnection(connection, m_processes);
1482     if (!proxy)
1483         return;
1484
1485     ASSERT(m_processesUsingGamepads.contains(proxy));
1486     processStoppedUsingGamepads(*proxy);
1487 }
1488
1489 void WebProcessPool::processStoppedUsingGamepads(WebProcessProxy& process)
1490 {
1491     bool wereAnyProcessesUsingGamepads = !m_processesUsingGamepads.isEmpty();
1492
1493     ASSERT(m_processesUsingGamepads.contains(&process));
1494     m_processesUsingGamepads.remove(&process);
1495
1496     if (wereAnyProcessesUsingGamepads && m_processesUsingGamepads.isEmpty())
1497         UIGamepadProvider::singleton().processPoolStoppedUsingGamepads(*this);
1498 }
1499
1500 void WebProcessPool::gamepadConnected(const UIGamepad& gamepad)
1501 {
1502     for (auto& process : m_processesUsingGamepads)
1503         process->send(Messages::WebProcess::GamepadConnected(gamepad.fullGamepadData()), 0);
1504 }
1505
1506 void WebProcessPool::gamepadDisconnected(const UIGamepad& gamepad)
1507 {
1508     for (auto& process : m_processesUsingGamepads)
1509         process->send(Messages::WebProcess::GamepadDisconnected(gamepad.index()), 0);
1510 }
1511
1512 void WebProcessPool::setInitialConnectedGamepads(const Vector<std::unique_ptr<UIGamepad>>& gamepads)
1513 {
1514     Vector<GamepadData> gamepadDatas;
1515     gamepadDatas.grow(gamepads.size());
1516     for (size_t i = 0; i < gamepads.size(); ++i) {
1517         if (!gamepads[i])
1518             continue;
1519         gamepadDatas[i] = gamepads[i]->fullGamepadData();
1520     }
1521
1522     for (auto& process : m_processesUsingGamepads)
1523         process->send(Messages::WebProcess::SetInitialGamepads(gamepadDatas), 0);
1524 }
1525
1526 #endif // ENABLE(GAMEPAD)
1527
1528 void WebProcessPool::setJavaScriptConfigurationFileEnabled(bool flag)
1529 {
1530     m_javaScriptConfigurationFileEnabled = flag;
1531 }
1532
1533 void WebProcessPool::garbageCollectJavaScriptObjects()
1534 {
1535     sendToAllProcesses(Messages::WebProcess::GarbageCollectJavaScriptObjects());
1536 }
1537
1538 void WebProcessPool::setJavaScriptGarbageCollectorTimerEnabled(bool flag)
1539 {
1540     sendToAllProcesses(Messages::WebProcess::SetJavaScriptGarbageCollectorTimerEnabled(flag));
1541 }
1542
1543 void WebProcessPool::addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, SessionID sessionID)
1544 {
1545     m_plugInAutoStartProvider.addAutoStartOriginHash(pageOrigin, plugInOriginHash, sessionID);
1546 }
1547
1548 void WebProcessPool::plugInDidReceiveUserInteraction(unsigned plugInOriginHash, SessionID sessionID)
1549 {
1550     m_plugInAutoStartProvider.didReceiveUserInteraction(plugInOriginHash, sessionID);
1551 }
1552
1553 Ref<API::Dictionary> WebProcessPool::plugInAutoStartOriginHashes() const
1554 {
1555     return m_plugInAutoStartProvider.autoStartOriginsTableCopy();
1556 }
1557
1558 void WebProcessPool::setPlugInAutoStartOriginHashes(API::Dictionary& dictionary)
1559 {
1560     m_plugInAutoStartProvider.setAutoStartOriginsTable(dictionary);
1561 }
1562
1563 void WebProcessPool::setPlugInAutoStartOrigins(API::Array& array)
1564 {
1565     m_plugInAutoStartProvider.setAutoStartOriginsArray(array);
1566 }
1567
1568 void WebProcessPool::setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary& dictionary, double time)
1569 {
1570     m_plugInAutoStartProvider.setAutoStartOriginsFilteringOutEntriesAddedAfterTime(dictionary, time);
1571 }
1572
1573 void WebProcessPool::registerSchemeForCustomProtocol(const String& scheme)
1574 {
1575     if (!globalURLSchemesWithCustomProtocolHandlers().contains(scheme))
1576         m_urlSchemesRegisteredForCustomProtocols.add(scheme);
1577     sendToNetworkingProcess(Messages::LegacyCustomProtocolManager::RegisterScheme(scheme));
1578 }
1579
1580 void WebProcessPool::unregisterSchemeForCustomProtocol(const String& scheme)
1581 {
1582     m_urlSchemesRegisteredForCustomProtocols.remove(scheme);
1583     sendToNetworkingProcess(Messages::LegacyCustomProtocolManager::UnregisterScheme(scheme));
1584 }
1585
1586 #if ENABLE(NETSCAPE_PLUGIN_API)
1587 void WebProcessPool::setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy policy, const String& host, const String& bundleIdentifier, const String& versionString)
1588 {
1589     auto& policiesForHost = m_pluginLoadClientPolicies.ensure(host, [] { return HashMap<String, HashMap<String, uint8_t>>(); }).iterator->value;
1590     auto& versionsToPolicies = policiesForHost.ensure(bundleIdentifier, [] { return HashMap<String, uint8_t>(); }).iterator->value;
1591     versionsToPolicies.set(versionString, policy);
1592
1593     sendToAllProcesses(Messages::WebProcess::SetPluginLoadClientPolicy(policy, host, bundleIdentifier, versionString));
1594 }
1595
1596 void WebProcessPool::resetPluginLoadClientPolicies(HashMap<String, HashMap<String, HashMap<String, uint8_t>>>&& pluginLoadClientPolicies)
1597 {
1598     m_pluginLoadClientPolicies = WTFMove(pluginLoadClientPolicies);
1599     sendToAllProcesses(Messages::WebProcess::ResetPluginLoadClientPolicies(m_pluginLoadClientPolicies));
1600 }
1601
1602 void WebProcessPool::clearPluginClientPolicies()
1603 {
1604     m_pluginLoadClientPolicies.clear();
1605     sendToAllProcesses(Messages::WebProcess::ClearPluginClientPolicies());
1606 }
1607 #endif
1608
1609 void WebProcessPool::setMemoryCacheDisabled(bool disabled)
1610 {
1611     m_memoryCacheDisabled = disabled;
1612     sendToAllProcesses(Messages::WebProcess::SetMemoryCacheDisabled(disabled));
1613 }
1614
1615 void WebProcessPool::setFontWhitelist(API::Array* array)
1616 {
1617     m_fontWhitelist.clear();
1618     if (array) {
1619         for (size_t i = 0; i < array->size(); ++i) {
1620             if (API::String* font = array->at<API::String>(i))
1621                 m_fontWhitelist.append(font->string());
1622         }
1623     }
1624 }
1625
1626 void WebProcessPool::updateHiddenPageThrottlingAutoIncreaseLimit()
1627 {
1628     // We're estimating an upper bound for a set of background timer fires for a page to be 200ms
1629     // (including all timer fires, all paging-in, and any resulting GC). To ensure this does not
1630     // result in more than 1% CPU load allow for one timer fire per 100x this duration.
1631     static int maximumTimerThrottlePerPageInMS = 200 * 100;
1632
1633     int limitInMilliseconds = maximumTimerThrottlePerPageInMS * m_hiddenPageThrottlingAutoIncreasesCounter.value();
1634     sendToAllProcesses(Messages::WebProcess::SetHiddenPageDOMTimerThrottlingIncreaseLimit(limitInMilliseconds));
1635 }
1636
1637 void WebProcessPool::reportWebContentCPUTime(Seconds cpuTime, uint64_t activityState)
1638 {
1639 #if PLATFORM(MAC)
1640     if (m_perActivityStateCPUUsageSampler)
1641         m_perActivityStateCPUUsageSampler->reportWebContentCPUTime(cpuTime, static_cast<WebCore::ActivityStateForCPUSampling>(activityState));
1642 #else
1643     UNUSED_PARAM(cpuTime);
1644     UNUSED_PARAM(activityState);
1645 #endif
1646 }
1647
1648 } // namespace WebKit