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