[iOS] Replace "node assistance" terminology in WebKit with "focused element"
[WebKit-https.git] / Source / WebKit / UIProcess / WebProcessPool.cpp
1 /*
2  * Copyright (C) 2010-2018 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 "APINavigation.h"
37 #include "APIPageConfiguration.h"
38 #include "APIProcessPoolConfiguration.h"
39 #include "ChildProcessMessages.h"
40 #include "DownloadProxy.h"
41 #include "DownloadProxyMessages.h"
42 #include "GamepadData.h"
43 #include "HighPerformanceGraphicsUsageSampler.h"
44 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
45 #include "LegacyCustomProtocolManagerMessages.h"
46 #endif
47 #include "LogInitialization.h"
48 #include "Logging.h"
49 #include "NetworkProcessCreationParameters.h"
50 #include "NetworkProcessMessages.h"
51 #include "NetworkProcessProxy.h"
52 #include "PerActivityStateCPUUsageSampler.h"
53 #include "PluginProcessManager.h"
54 #include "SandboxExtension.h"
55 #include "ServiceWorkerProcessProxy.h"
56 #include "StatisticsData.h"
57 #include "TextChecker.h"
58 #include "UIGamepad.h"
59 #include "UIGamepadProvider.h"
60 #include "WKContextPrivate.h"
61 #include "WebAutomationSession.h"
62 #include "WebBackForwardList.h"
63 #include "WebBackForwardListItem.h"
64 #include "WebCertificateInfo.h"
65 #include "WebContextSupplement.h"
66 #include "WebCookieManagerProxy.h"
67 #include "WebCoreArgumentCoders.h"
68 #include "WebGeolocationManagerProxy.h"
69 #include "WebKit2Initialize.h"
70 #include "WebMemorySampler.h"
71 #include "WebNotificationManagerProxy.h"
72 #include "WebPageGroup.h"
73 #include "WebPreferences.h"
74 #include "WebPreferencesKeys.h"
75 #include "WebProcessCreationParameters.h"
76 #include "WebProcessMessages.h"
77 #include "WebProcessPoolMessages.h"
78 #include "WebProcessProxy.h"
79 #include "WebsiteDataStore.h"
80 #include "WebsiteDataStoreParameters.h"
81 #include <JavaScriptCore/JSCInlines.h>
82 #include <WebCore/ApplicationCacheStorage.h>
83 #include <WebCore/LogInitialization.h>
84 #include <WebCore/MockRealtimeMediaSourceCenter.h>
85 #include <WebCore/NetworkStorageSession.h>
86 #include <WebCore/PlatformScreen.h>
87 #include <WebCore/Process.h>
88 #include <WebCore/ProcessWarming.h>
89 #include <WebCore/ResourceRequest.h>
90 #include <pal/SessionID.h>
91 #include <wtf/Language.h>
92 #include <wtf/MainThread.h>
93 #include <wtf/NeverDestroyed.h>
94 #include <wtf/ProcessPrivilege.h>
95 #include <wtf/RunLoop.h>
96 #include <wtf/Scope.h>
97 #include <wtf/URLParser.h>
98 #include <wtf/WallTime.h>
99 #include <wtf/text/StringBuilder.h>
100
101 #if ENABLE(SERVICE_CONTROLS)
102 #include "ServicesController.h"
103 #endif
104
105 #if ENABLE(REMOTE_INSPECTOR)
106 #include <JavaScriptCore/RemoteInspector.h>
107 #endif
108
109 #if OS(LINUX)
110 #include "MemoryPressureMonitor.h"
111 #endif
112
113 #if PLATFORM(WAYLAND)
114 #include "WaylandCompositor.h"
115 #include <WebCore/PlatformDisplay.h>
116 #endif
117
118 #ifndef NDEBUG
119 #include <wtf/RefCountedLeakCounter.h>
120 #endif
121
122 namespace WebKit {
123 using namespace WebCore;
124
125 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, processPoolCounter, ("WebProcessPool"));
126
127 const Seconds serviceWorkerTerminationDelay { 5_s };
128
129 static uint64_t generateListenerIdentifier()
130 {
131     static uint64_t nextIdentifier = 1;
132     return nextIdentifier++;
133 }
134
135 static HashMap<uint64_t, Function<void(WebProcessPool&)>>& processPoolCreationListenerFunctionMap()
136 {
137     static NeverDestroyed<HashMap<uint64_t, Function<void(WebProcessPool&)>>> map;
138     return map;
139 }
140
141 uint64_t WebProcessPool::registerProcessPoolCreationListener(Function<void(WebProcessPool&)>&& function)
142 {
143     ASSERT(function);
144
145     auto identifier = generateListenerIdentifier();
146     processPoolCreationListenerFunctionMap().set(identifier, WTFMove(function));
147     return identifier;
148 }
149
150 void WebProcessPool::unregisterProcessPoolCreationListener(uint64_t identifier)
151 {
152     processPoolCreationListenerFunctionMap().remove(identifier);
153 }
154
155 Ref<WebProcessPool> WebProcessPool::create(API::ProcessPoolConfiguration& configuration)
156 {
157     InitializeWebKit2();
158     return adoptRef(*new WebProcessPool(configuration));
159 }
160
161 void WebProcessPool::notifyThisWebProcessPoolWasCreated()
162 {
163     auto& listenerMap = processPoolCreationListenerFunctionMap();
164
165     Vector<uint64_t> identifiers;
166     identifiers.reserveInitialCapacity(listenerMap.size());
167     for (auto identifier : listenerMap.keys())
168         identifiers.uncheckedAppend(identifier);
169
170     for (auto identifier : identifiers) {
171         auto iterator = listenerMap.find(identifier);
172         if (iterator == listenerMap.end())
173             continue;
174
175         // To make sure the Function object stays alive until after the function call has been made,
176         // we temporarily move it out of the map.
177         // This protects it from the Function calling unregisterProcessPoolCreationListener thereby
178         // removing itself from the map of listeners.
179         // If the identifier still exists in the map later, we move it back in.
180         Function<void(WebProcessPool&)> function = WTFMove(iterator->value);
181         function(*this);
182
183         iterator = listenerMap.find(identifier);
184         if (iterator != listenerMap.end()) {
185             ASSERT(!iterator->value);
186             iterator->value = WTFMove(function);
187         }
188     }
189 }
190
191 static Vector<WebProcessPool*>& processPools()
192 {
193     static NeverDestroyed<Vector<WebProcessPool*>> processPools;
194     return processPools;
195 }
196
197 const Vector<WebProcessPool*>& WebProcessPool::allProcessPools()
198 {
199     return processPools();
200 }
201
202 static Ref<WebsiteDataStoreConfiguration> legacyWebsiteDataStoreConfiguration(API::ProcessPoolConfiguration& processPoolConfiguration)
203 {
204     auto configuration = WebsiteDataStoreConfiguration::create();
205
206     configuration->setCacheStorageDirectory(String(API::WebsiteDataStore::defaultCacheStorageDirectory()));
207     configuration->setServiceWorkerRegistrationDirectory(String(API::WebsiteDataStore::defaultServiceWorkerRegistrationDirectory()));
208     configuration->setLocalStorageDirectory(String(processPoolConfiguration.localStorageDirectory()));
209     configuration->setWebSQLDatabaseDirectory(String(processPoolConfiguration.webSQLDatabaseDirectory()));
210     configuration->setApplicationCacheDirectory(String(processPoolConfiguration.applicationCacheDirectory()));
211     configuration->setApplicationCacheFlatFileSubdirectoryName(String(processPoolConfiguration.applicationCacheFlatFileSubdirectoryName()));
212     configuration->setMediaCacheDirectory(String(processPoolConfiguration.mediaCacheDirectory()));
213     configuration->setMediaKeysStorageDirectory(String(processPoolConfiguration.mediaKeysStorageDirectory()));
214     configuration->setResourceLoadStatisticsDirectory(String(processPoolConfiguration.resourceLoadStatisticsDirectory()));
215     configuration->setNetworkCacheDirectory(String(processPoolConfiguration.diskCacheDirectory()));
216     configuration->setJavaScriptConfigurationDirectory(String(processPoolConfiguration.javaScriptConfigurationDirectory()));
217
218     return configuration;
219 }
220
221 static HashSet<String, ASCIICaseInsensitiveHash>& globalURLSchemesWithCustomProtocolHandlers()
222 {
223     static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> set;
224     return set;
225 }
226
227 WebProcessPool::WebProcessPool(API::ProcessPoolConfiguration& configuration)
228     : m_configuration(configuration.copy())
229     , m_defaultPageGroup(WebPageGroup::create())
230     , m_injectedBundleClient(std::make_unique<API::InjectedBundleClient>())
231     , m_automationClient(std::make_unique<API::AutomationClient>())
232     , m_downloadClient(std::make_unique<API::DownloadClient>())
233     , m_historyClient(std::make_unique<API::LegacyContextHistoryClient>())
234     , m_customProtocolManagerClient(std::make_unique<API::CustomProtocolManagerClient>())
235     , m_visitedLinkStore(VisitedLinkStore::create())
236 #if PLATFORM(MAC)
237     , m_highPerformanceGraphicsUsageSampler(std::make_unique<HighPerformanceGraphicsUsageSampler>(*this))
238     , m_perActivityStateCPUUsageSampler(std::make_unique<PerActivityStateCPUUsageSampler>(*this))
239 #endif
240     , m_alwaysRunsAtBackgroundPriority(m_configuration->alwaysRunsAtBackgroundPriority())
241     , m_shouldTakeUIBackgroundAssertion(m_configuration->shouldTakeUIBackgroundAssertion())
242     , m_userObservablePageCounter([this](RefCounterEvent) { updateProcessSuppressionState(); })
243     , m_processSuppressionDisabledForPageCounter([this](RefCounterEvent) { updateProcessSuppressionState(); })
244     , m_hiddenPageThrottlingAutoIncreasesCounter([this](RefCounterEvent) { m_hiddenPageThrottlingTimer.startOneShot(0_s); })
245     , m_hiddenPageThrottlingTimer(RunLoop::main(), this, &WebProcessPool::updateHiddenPageThrottlingAutoIncreaseLimit)
246     , m_serviceWorkerProcessesTerminationTimer(RunLoop::main(), this, &WebProcessPool::terminateServiceWorkerProcesses)
247 #if PLATFORM(IOS_FAMILY)
248     , m_foregroundWebProcessCounter([this](RefCounterEvent) { updateProcessAssertions(); })
249     , m_backgroundWebProcessCounter([this](RefCounterEvent) { updateProcessAssertions(); })
250 #endif
251 {
252     static std::once_flag onceFlag;
253     std::call_once(onceFlag, [] {
254         WTF::setProcessPrivileges(allPrivileges());
255         WebCore::NetworkStorageSession::permitProcessToUseCookieAPI(true);
256         Process::setIdentifier(generateObjectIdentifier<WebCore::ProcessIdentifierType>());
257     });
258
259     if (m_configuration->shouldHaveLegacyDataStore())
260         m_websiteDataStore = API::WebsiteDataStore::createLegacy(legacyWebsiteDataStoreConfiguration(m_configuration));
261
262     if (!m_websiteDataStore && API::WebsiteDataStore::defaultDataStoreExists())
263         m_websiteDataStore = API::WebsiteDataStore::defaultDataStore();
264
265     for (auto& scheme : m_configuration->alwaysRevalidatedURLSchemes())
266         m_schemesToRegisterAsAlwaysRevalidated.add(scheme);
267
268     for (const auto& urlScheme : m_configuration->cachePartitionedURLSchemes())
269         m_schemesToRegisterAsCachePartitioned.add(urlScheme);
270
271     platformInitialize();
272
273 #if OS(LINUX)
274     MemoryPressureMonitor::singleton().start();
275 #endif
276
277     addMessageReceiver(Messages::WebProcessPool::messageReceiverName(), *this);
278
279     // NOTE: These sub-objects must be initialized after m_messageReceiverMap..
280     addSupplement<WebCookieManagerProxy>();
281     addSupplement<WebGeolocationManagerProxy>();
282     addSupplement<WebNotificationManagerProxy>();
283 #if ENABLE(MEDIA_SESSION)
284     addSupplement<WebMediaSessionFocusManager>();
285 #endif
286
287     processPools().append(this);
288
289     addLanguageChangeObserver(this, languageChanged);
290
291     resolvePathsForSandboxExtensions();
292
293 #if !LOG_DISABLED || !RELEASE_LOG_DISABLED
294     WebCore::initializeLogChannelsIfNecessary();
295     WebKit::initializeLogChannelsIfNecessary();
296 #endif // !LOG_DISABLED || !RELEASE_LOG_DISABLED
297
298 #ifndef NDEBUG
299     processPoolCounter.increment();
300 #endif
301
302     notifyThisWebProcessPoolWasCreated();
303
304     updateMaxSuspendedPageCount();
305 }
306
307 WebProcessPool::~WebProcessPool()
308 {
309     bool removed = processPools().removeFirst(this);
310     ASSERT_UNUSED(removed, removed);
311
312     removeLanguageChangeObserver(this);
313
314     m_messageReceiverMap.invalidate();
315
316     for (auto& supplement : m_supplements.values()) {
317         supplement->processPoolDestroyed();
318         supplement->clearProcessPool();
319     }
320
321     invalidateCallbackMap(m_dictionaryCallbacks, CallbackBase::Error::OwnerWasInvalidated);
322
323     platformInvalidateContext();
324
325 #ifndef NDEBUG
326     processPoolCounter.decrement();
327 #endif
328
329     if (m_networkProcess)
330         m_networkProcess->shutDownProcess();
331
332 #if ENABLE(GAMEPAD)
333     if (!m_processesUsingGamepads.isEmpty())
334         UIGamepadProvider::singleton().processPoolStoppedUsingGamepads(*this);
335 #endif
336
337     // Only remaining processes should be pre-warmed ones as other keep the process pool alive.
338     while (!m_processes.isEmpty()) {
339         auto& process = m_processes.first();
340
341         ASSERT(process->isPrewarmed());
342         // We need to be the only one holding a reference to the pre-warmed process so that it gets destroyed.
343         // WebProcessProxies currently always expect to have a WebProcessPool.
344         ASSERT(process->hasOneRef());
345
346         process->shutDown();
347     }
348 }
349
350 void WebProcessPool::initializeClient(const WKContextClientBase* client)
351 {
352     m_client.initialize(client);
353 }
354
355 void WebProcessPool::setInjectedBundleClient(std::unique_ptr<API::InjectedBundleClient>&& client)
356 {
357     if (!client)
358         m_injectedBundleClient = std::make_unique<API::InjectedBundleClient>();
359     else
360         m_injectedBundleClient = WTFMove(client);
361 }
362
363 void WebProcessPool::initializeConnectionClient(const WKContextConnectionClientBase* client)
364 {
365     m_connectionClient.initialize(client);
366 }
367
368 void WebProcessPool::setHistoryClient(std::unique_ptr<API::LegacyContextHistoryClient>&& historyClient)
369 {
370     if (!historyClient)
371         m_historyClient = std::make_unique<API::LegacyContextHistoryClient>();
372     else
373         m_historyClient = WTFMove(historyClient);
374 }
375
376 void WebProcessPool::setDownloadClient(std::unique_ptr<API::DownloadClient>&& downloadClient)
377 {
378     if (!downloadClient)
379         m_downloadClient = std::make_unique<API::DownloadClient>();
380     else
381         m_downloadClient = WTFMove(downloadClient);
382 }
383
384 void WebProcessPool::setAutomationClient(std::unique_ptr<API::AutomationClient>&& automationClient)
385 {
386     if (!automationClient)
387         m_automationClient = std::make_unique<API::AutomationClient>();
388     else
389         m_automationClient = WTFMove(automationClient);
390 }
391
392 void WebProcessPool::setLegacyCustomProtocolManagerClient(std::unique_ptr<API::CustomProtocolManagerClient>&& customProtocolManagerClient)
393 {
394 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
395     if (!customProtocolManagerClient)
396         m_customProtocolManagerClient = std::make_unique<API::CustomProtocolManagerClient>();
397     else
398         m_customProtocolManagerClient = WTFMove(customProtocolManagerClient);
399 #endif
400 }
401
402 void WebProcessPool::setMaximumNumberOfProcesses(unsigned maximumNumberOfProcesses)
403 {
404     m_configuration->setMaximumProcessCount(maximumNumberOfProcesses);
405 }
406
407 void WebProcessPool::setCustomWebContentServiceBundleIdentifier(const String& customWebContentServiceBundleIdentifier)
408 {
409     // Guard against API misuse.
410     if (!customWebContentServiceBundleIdentifier.isAllASCII())
411         CRASH();
412
413     m_configuration->setCustomWebContentServiceBundleIdentifier(customWebContentServiceBundleIdentifier);
414 }
415
416 IPC::Connection* WebProcessPool::networkingProcessConnection()
417 {
418     return m_networkProcess->connection();
419 }
420
421 void WebProcessPool::languageChanged(void* context)
422 {
423     static_cast<WebProcessPool*>(context)->languageChanged();
424 }
425
426 void WebProcessPool::languageChanged()
427 {
428     sendToAllProcesses(Messages::WebProcess::UserPreferredLanguagesChanged(userPreferredLanguages()));
429 #if USE(SOUP)
430     if (m_networkProcess)
431         m_networkProcess->send(Messages::NetworkProcess::UserPreferredLanguagesChanged(userPreferredLanguages()), 0);
432 #endif
433 }
434
435 void WebProcessPool::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
436 {
437     sendToAllProcesses(Messages::WebProcess::FullKeyboardAccessModeChanged(fullKeyboardAccessEnabled));
438 }
439
440 #if OS(LINUX)
441 void WebProcessPool::sendMemoryPressureEvent(bool isCritical)
442 {
443     sendToAllProcesses(Messages::ChildProcess::DidReceiveMemoryPressureEvent(isCritical));
444     sendToNetworkingProcess(Messages::ChildProcess::DidReceiveMemoryPressureEvent(isCritical));
445 #if ENABLE(NETSCAPE_PLUGIN_API)
446     PluginProcessManager::singleton().sendMemoryPressureEvent(isCritical);
447 #endif
448 }
449 #endif
450
451 void WebProcessPool::textCheckerStateChanged()
452 {
453     sendToAllProcesses(Messages::WebProcess::SetTextCheckerState(TextChecker::state()));
454 }
455
456 void WebProcessPool::screenPropertiesStateChanged()
457 {
458 #if PLATFORM(MAC)
459     auto screenProperties = WebCore::collectScreenProperties();
460     sendToAllProcesses(Messages::WebProcess::SetScreenProperties(screenProperties));
461 #endif
462 }
463
464 NetworkProcessProxy& WebProcessPool::ensureNetworkProcess(WebsiteDataStore* withWebsiteDataStore)
465 {
466     if (m_networkProcess) {
467         if (withWebsiteDataStore) {
468             m_networkProcess->addSession(makeRef(*withWebsiteDataStore));
469             withWebsiteDataStore->clearPendingCookies();
470         }
471         return *m_networkProcess;
472     }
473
474     m_networkProcess = std::make_unique<NetworkProcessProxy>(*this);
475
476     NetworkProcessCreationParameters parameters;
477
478     if (m_websiteDataStore) {
479         parameters.defaultSessionPendingCookies = copyToVector(m_websiteDataStore->websiteDataStore().pendingCookies());
480         m_websiteDataStore->websiteDataStore().clearPendingCookies();
481     }
482
483     parameters.cacheModel = cacheModel();
484     parameters.canHandleHTTPSServerTrustEvaluation = m_canHandleHTTPSServerTrustEvaluation;
485
486     for (auto& scheme : globalURLSchemesWithCustomProtocolHandlers())
487         parameters.urlSchemesRegisteredForCustomProtocols.append(scheme);
488
489     for (auto& scheme : m_urlSchemesRegisteredForCustomProtocols)
490         parameters.urlSchemesRegisteredForCustomProtocols.append(scheme);
491
492     parameters.diskCacheDirectory = m_configuration->diskCacheDirectory();
493     if (!parameters.diskCacheDirectory.isEmpty())
494         SandboxExtension::createHandleForReadWriteDirectory(parameters.diskCacheDirectory, parameters.diskCacheDirectoryExtensionHandle);
495 #if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
496     parameters.shouldEnableNetworkCacheSpeculativeRevalidation = m_configuration->diskCacheSpeculativeValidationEnabled();
497 #endif
498
499 #if PLATFORM(IOS_FAMILY)
500     String cookieStorageDirectory = this->cookieStorageDirectory();
501     if (!cookieStorageDirectory.isEmpty())
502         SandboxExtension::createHandleForReadWriteDirectory(cookieStorageDirectory, parameters.cookieStorageDirectoryExtensionHandle);
503
504     String containerCachesDirectory = this->networkingCachesDirectory();
505     if (!containerCachesDirectory.isEmpty())
506         SandboxExtension::createHandleForReadWriteDirectory(containerCachesDirectory, parameters.containerCachesDirectoryExtensionHandle);
507
508     String parentBundleDirectory = this->parentBundleDirectory();
509     if (!parentBundleDirectory.isEmpty())
510         SandboxExtension::createHandle(parentBundleDirectory, SandboxExtension::Type::ReadOnly, parameters.parentBundleDirectoryExtensionHandle);
511
512 #if ENABLE(INDEXED_DATABASE)
513     SandboxExtension::createHandleForTemporaryFile(emptyString(), SandboxExtension::Type::ReadWrite, parameters.indexedDatabaseTempBlobDirectoryExtensionHandle);
514 #endif
515 #endif
516
517     parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession;
518     parameters.presentingApplicationPID = m_configuration->presentingApplicationPID();
519
520     parameters.urlSchemesRegisteredAsSecure = copyToVector(m_schemesToRegisterAsSecure);
521     parameters.urlSchemesRegisteredAsBypassingContentSecurityPolicy = copyToVector(m_schemesToRegisterAsBypassingContentSecurityPolicy);
522     parameters.urlSchemesRegisteredAsLocal = copyToVector(m_schemesToRegisterAsLocal);
523     parameters.urlSchemesRegisteredAsNoAccess = copyToVector(m_schemesToRegisterAsNoAccess);
524     parameters.urlSchemesRegisteredAsDisplayIsolated = copyToVector(m_schemesToRegisterAsDisplayIsolated);
525     parameters.urlSchemesRegisteredAsCORSEnabled = copyToVector(m_schemesToRegisterAsCORSEnabled);
526     parameters.urlSchemesRegisteredAsCanDisplayOnlyIfCanRequest = copyToVector(m_schemesToRegisterAsCanDisplayOnlyIfCanRequest);
527
528 #if ENABLE(INDEXED_DATABASE)
529     // *********
530     // IMPORTANT: Do not change the directory structure for indexed databases on disk without first consulting a reviewer from Apple (<rdar://problem/17454712>)
531     // *********
532     parameters.indexedDatabaseDirectory = m_configuration->indexedDBDatabaseDirectory();
533     if (parameters.indexedDatabaseDirectory.isEmpty())
534         parameters.indexedDatabaseDirectory = API::WebsiteDataStore::defaultDataStore()->websiteDataStore().parameters().indexedDatabaseDirectory;
535     
536     SandboxExtension::createHandleForReadWriteDirectory(parameters.indexedDatabaseDirectory, parameters.indexedDatabaseDirectoryExtensionHandle);
537 #endif
538
539 #if ENABLE(SERVICE_WORKER)
540     if (m_websiteDataStore)
541         parameters.serviceWorkerRegistrationDirectory = m_websiteDataStore->websiteDataStore().resolvedServiceWorkerRegistrationDirectory();
542     if (!parameters.serviceWorkerRegistrationDirectory)
543         parameters.serviceWorkerRegistrationDirectory =  API::WebsiteDataStore::defaultServiceWorkerRegistrationDirectory();
544     SandboxExtension::createHandleForReadWriteDirectory(parameters.serviceWorkerRegistrationDirectory, parameters.serviceWorkerRegistrationDirectoryExtensionHandle);
545
546     if (!m_schemesServiceWorkersCanHandle.isEmpty())
547         parameters.urlSchemesServiceWorkersCanHandle = copyToVector(m_schemesServiceWorkersCanHandle);
548
549     parameters.shouldDisableServiceWorkerProcessTerminationDelay = m_shouldDisableServiceWorkerProcessTerminationDelay;
550 #endif
551
552     // Add any platform specific parameters
553     platformInitializeNetworkProcess(parameters);
554
555     // Initialize the network process.
556     m_networkProcess->send(Messages::NetworkProcess::InitializeNetworkProcess(parameters), 0);
557
558     if (WebPreferences::anyPagesAreUsingPrivateBrowsing())
559         m_networkProcess->send(Messages::NetworkProcess::AddWebsiteDataStore(WebsiteDataStoreParameters::legacyPrivateSessionParameters()), 0);
560
561 #if PLATFORM(COCOA)
562     m_networkProcess->send(Messages::NetworkProcess::SetQOS(networkProcessLatencyQOS(), networkProcessThroughputQOS()), 0);
563 #endif
564
565     if (m_didNetworkProcessCrash) {
566         m_didNetworkProcessCrash = false;
567         reinstateNetworkProcessAssertionState(*m_networkProcess);
568     }
569
570     if (withWebsiteDataStore) {
571         m_networkProcess->addSession(makeRef(*withWebsiteDataStore));
572         withWebsiteDataStore->clearPendingCookies();
573     }
574
575     // Make sure the network process knows about all the sessions that have been registered before it started.
576     for (auto& sessionID : m_sessionToPagesMap.keys()) {
577         if (auto* websiteDataStore = WebsiteDataStore::existingNonDefaultDataStoreForSessionID(sessionID))
578             m_networkProcess->addSession(*websiteDataStore);
579     }
580
581     if (m_websiteDataStore)
582         m_websiteDataStore->websiteDataStore().didCreateNetworkProcess();
583
584     return *m_networkProcess;
585 }
586
587 void WebProcessPool::networkProcessCrashed(NetworkProcessProxy& networkProcessProxy, Vector<std::pair<RefPtr<WebProcessProxy>, Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>>&& pendingReplies)
588 {
589     ASSERT(m_networkProcess);
590     ASSERT(&networkProcessProxy == m_networkProcess.get());
591     m_didNetworkProcessCrash = true;
592
593     for (auto& supplement : m_supplements.values())
594         supplement->processDidClose(&networkProcessProxy);
595
596     m_client.networkProcessDidCrash(this);
597
598     if (m_automationSession)
599         m_automationSession->terminate();
600
601     // Leave the process proxy around during client call, so that the client could query the process identifier.
602     m_networkProcess = nullptr;
603
604     // Attempt to re-launch.
605     if (pendingReplies.isEmpty())
606         return;
607     auto& newNetworkProcess = ensureNetworkProcess();
608     for (auto& reply : pendingReplies)
609         newNetworkProcess.getNetworkProcessConnection(*reply.first, WTFMove(reply.second));
610 }
611
612 void WebProcessPool::getNetworkProcessConnection(WebProcessProxy& webProcessProxy, Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply&& reply)
613 {
614     ensureNetworkProcess();
615     ASSERT(m_networkProcess);
616
617     m_networkProcess->getNetworkProcessConnection(webProcessProxy, WTFMove(reply));
618 }
619
620 #if ENABLE(SERVICE_WORKER)
621 void WebProcessPool::establishWorkerContextConnectionToNetworkProcess(NetworkProcessProxy& proxy, SecurityOriginData&& securityOrigin, Optional<PAL::SessionID> sessionID)
622 {
623     ASSERT_UNUSED(proxy, &proxy == m_networkProcess.get());
624
625     if (m_serviceWorkerProcesses.contains(securityOrigin))
626         return;
627
628     m_mayHaveRegisteredServiceWorkers.clear();
629
630     WebsiteDataStore* websiteDataStore = nullptr;
631     if (sessionID)
632         websiteDataStore = WebsiteDataStore::existingNonDefaultDataStoreForSessionID(*sessionID);
633
634     if (!websiteDataStore) {
635         if (!m_websiteDataStore)
636             m_websiteDataStore = API::WebsiteDataStore::defaultDataStore().ptr();
637         websiteDataStore = &m_websiteDataStore->websiteDataStore();
638     }
639
640     if (m_serviceWorkerProcesses.isEmpty())
641         sendToAllProcesses(Messages::WebProcess::RegisterServiceWorkerClients { });
642
643     auto serviceWorkerProcessProxy = ServiceWorkerProcessProxy::create(*this, securityOrigin, *websiteDataStore);
644     m_serviceWorkerProcesses.add(WTFMove(securityOrigin), serviceWorkerProcessProxy.ptr());
645
646     updateProcessAssertions();
647     initializeNewWebProcess(serviceWorkerProcessProxy, *websiteDataStore);
648
649     auto* serviceWorkerProcessProxyPtr = serviceWorkerProcessProxy.ptr();
650     m_processes.append(WTFMove(serviceWorkerProcessProxy));
651
652     serviceWorkerProcessProxyPtr->start(m_serviceWorkerPreferences ? m_serviceWorkerPreferences.value() : m_defaultPageGroup->preferences().store(), sessionID);
653     if (!m_serviceWorkerUserAgent.isNull())
654         serviceWorkerProcessProxyPtr->setUserAgent(m_serviceWorkerUserAgent);
655 }
656 #endif
657
658 void WebProcessPool::disableServiceWorkerProcessTerminationDelay()
659 {
660 #if ENABLE(SERVICE_WORKER)
661     if (m_shouldDisableServiceWorkerProcessTerminationDelay)
662         return;
663
664     m_shouldDisableServiceWorkerProcessTerminationDelay = true;
665     if (m_networkProcess)
666         m_networkProcess->send(Messages::NetworkProcess::DisableServiceWorkerProcessTerminationDelay(), 0);
667 #endif
668 }
669
670 void WebProcessPool::willStartUsingPrivateBrowsing()
671 {
672     for (auto* processPool : allProcessPools())
673         processPool->setAnyPageGroupMightHavePrivateBrowsingEnabled(true);
674 }
675
676 void WebProcessPool::willStopUsingPrivateBrowsing()
677 {
678     for (auto* processPool : allProcessPools())
679         processPool->setAnyPageGroupMightHavePrivateBrowsingEnabled(false);
680 }
681
682 void WebProcessPool::windowServerConnectionStateChanged()
683 {
684     size_t processCount = m_processes.size();
685     for (size_t i = 0; i < processCount; ++i)
686         m_processes[i]->windowServerConnectionStateChanged();
687 }
688
689 void WebProcessPool::setAnyPageGroupMightHavePrivateBrowsingEnabled(bool privateBrowsingEnabled)
690 {
691     if (privateBrowsingEnabled) {
692         sendToNetworkingProcess(Messages::NetworkProcess::AddWebsiteDataStore(WebsiteDataStoreParameters::legacyPrivateSessionParameters()));
693         sendToAllProcesses(Messages::WebProcess::AddWebsiteDataStore(WebsiteDataStoreParameters::legacyPrivateSessionParameters()));
694     } else {
695         networkProcess()->removeSession(PAL::SessionID::legacyPrivateSessionID());
696         sendToAllProcesses(Messages::WebProcess::DestroySession(PAL::SessionID::legacyPrivateSessionID()));
697     }
698 }
699
700 void (*s_invalidMessageCallback)(WKStringRef messageName);
701
702 void WebProcessPool::setInvalidMessageCallback(void (*invalidMessageCallback)(WKStringRef messageName))
703 {
704     s_invalidMessageCallback = invalidMessageCallback;
705 }
706
707 void WebProcessPool::didReceiveInvalidMessage(const IPC::StringReference& messageReceiverName, const IPC::StringReference& messageName)
708 {
709     if (!s_invalidMessageCallback)
710         return;
711
712     StringBuilder messageNameStringBuilder;
713     messageNameStringBuilder.append(messageReceiverName.data(), messageReceiverName.size());
714     messageNameStringBuilder.append('.');
715     messageNameStringBuilder.append(messageName.data(), messageName.size());
716
717     s_invalidMessageCallback(toAPI(API::String::create(messageNameStringBuilder.toString()).ptr()));
718 }
719
720 void WebProcessPool::processDidCachePage(WebProcessProxy* process)
721 {
722     if (m_processWithPageCache && m_processWithPageCache != process)
723         m_processWithPageCache->releasePageCache();
724     m_processWithPageCache = process;
725 }
726
727 void WebProcessPool::resolvePathsForSandboxExtensions()
728 {
729     m_resolvedPaths.injectedBundlePath = resolvePathForSandboxExtension(injectedBundlePath());
730     m_resolvedPaths.applicationCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->applicationCacheDirectory());
731     m_resolvedPaths.webSQLDatabaseDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->webSQLDatabaseDirectory());
732     m_resolvedPaths.mediaCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaCacheDirectory());
733     m_resolvedPaths.mediaKeyStorageDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaKeysStorageDirectory());
734     m_resolvedPaths.indexedDatabaseDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->indexedDBDatabaseDirectory());
735
736     m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.reserveCapacity(m_configuration->additionalReadAccessAllowedPaths().size());
737     for (const auto& path : m_configuration->additionalReadAccessAllowedPaths())
738         m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.uncheckedAppend(resolvePathForSandboxExtension(path.data()));
739
740     platformResolvePathsForSandboxExtensions();
741 }
742
743 WebProcessProxy& WebProcessPool::createNewWebProcess(WebsiteDataStore& websiteDataStore, WebProcessProxy::IsPrewarmed isPrewarmed)
744 {
745     auto processProxy = WebProcessProxy::create(*this, websiteDataStore, isPrewarmed);
746     auto& process = processProxy.get();
747     initializeNewWebProcess(process, websiteDataStore);
748     m_processes.append(WTFMove(processProxy));
749     if (isPrewarmed == WebProcessProxy::IsPrewarmed::Yes) {
750         ASSERT(!m_prewarmedProcess);
751         m_prewarmedProcess = &process;
752         
753         m_prewarmedProcess->send(Messages::WebProcess::PrewarmGlobally(), 0);
754     }
755
756     if (m_serviceWorkerProcessesTerminationTimer.isActive())
757         m_serviceWorkerProcessesTerminationTimer.stop();
758
759     return process;
760 }
761
762 RefPtr<WebProcessProxy> WebProcessPool::tryTakePrewarmedProcess(WebsiteDataStore& websiteDataStore)
763 {
764     if (!m_prewarmedProcess)
765         return nullptr;
766
767     ASSERT(m_prewarmedProcess->isPrewarmed());
768     m_prewarmedProcess->markIsNoLongerInPrewarmedPool();
769     if (&m_prewarmedProcess->websiteDataStore() != &websiteDataStore)
770         m_prewarmedProcess->send(Messages::WebProcess::AddWebsiteDataStore(websiteDataStore.parameters()), 0);
771
772     return std::exchange(m_prewarmedProcess, nullptr);
773 }
774
775 #if PLATFORM(MAC)
776 static void displayReconfigurationCallBack(CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *userInfo)
777 {
778     auto screenProperties = WebCore::collectScreenProperties();
779     for (auto& processPool : WebProcessPool::allProcessPools()) {
780         processPool->sendToAllProcesses(Messages::WebProcess::SetScreenProperties(screenProperties));
781 #if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
782         processPool->sendToAllProcesses(Messages::WebProcess::DisplayConfigurationChanged(display, flags));
783 #endif
784     }
785 }
786
787 static void registerDisplayConfigurationCallback()
788 {
789     static std::once_flag onceFlag;
790     std::call_once(
791         onceFlag,
792         [] {
793             CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallBack, nullptr);
794         });
795 }
796 #endif
797
798 void WebProcessPool::initializeNewWebProcess(WebProcessProxy& process, WebsiteDataStore& websiteDataStore)
799 {
800     auto initializationActivityToken = process.throttler().backgroundActivityToken();
801     auto scopeExit = makeScopeExit([&process, initializationActivityToken] {
802         // Round-trip to the Web Content process before releasing the
803         // initialization activity token, so that we're sure that all
804         // messages sent from this function have been handled.
805         process.isResponsive([initializationActivityToken] (bool) { });
806     });
807
808     ensureNetworkProcess();
809
810     WebProcessCreationParameters parameters;
811
812     websiteDataStore.resolveDirectoriesIfNecessary();
813
814     parameters.injectedBundlePath = m_resolvedPaths.injectedBundlePath;
815     if (!parameters.injectedBundlePath.isEmpty())
816         SandboxExtension::createHandleWithoutResolvingPath(parameters.injectedBundlePath, SandboxExtension::Type::ReadOnly, parameters.injectedBundlePathExtensionHandle);
817
818     parameters.additionalSandboxExtensionHandles.allocate(m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.size());
819     for (size_t i = 0, size = m_resolvedPaths.additionalWebProcessSandboxExtensionPaths.size(); i < size; ++i)
820         SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.additionalWebProcessSandboxExtensionPaths[i], SandboxExtension::Type::ReadOnly, parameters.additionalSandboxExtensionHandles[i]);
821
822     parameters.applicationCacheDirectory = websiteDataStore.resolvedApplicationCacheDirectory();
823     if (parameters.applicationCacheDirectory.isEmpty())
824         parameters.applicationCacheDirectory = m_resolvedPaths.applicationCacheDirectory;
825     if (!parameters.applicationCacheDirectory.isEmpty())
826         SandboxExtension::createHandleWithoutResolvingPath(parameters.applicationCacheDirectory, SandboxExtension::Type::ReadWrite, parameters.applicationCacheDirectoryExtensionHandle);
827
828     parameters.applicationCacheFlatFileSubdirectoryName = m_configuration->applicationCacheFlatFileSubdirectoryName();
829
830     parameters.webSQLDatabaseDirectory = websiteDataStore.resolvedDatabaseDirectory();
831     if (parameters.webSQLDatabaseDirectory.isEmpty())
832         parameters.webSQLDatabaseDirectory = m_resolvedPaths.webSQLDatabaseDirectory;
833     if (!parameters.webSQLDatabaseDirectory.isEmpty())
834         SandboxExtension::createHandleWithoutResolvingPath(parameters.webSQLDatabaseDirectory, SandboxExtension::Type::ReadWrite, parameters.webSQLDatabaseDirectoryExtensionHandle);
835
836     parameters.mediaCacheDirectory = websiteDataStore.resolvedMediaCacheDirectory();
837     if (parameters.mediaCacheDirectory.isEmpty())
838         parameters.mediaCacheDirectory = m_resolvedPaths.mediaCacheDirectory;
839     if (!parameters.mediaCacheDirectory.isEmpty())
840         SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaCacheDirectory, SandboxExtension::Type::ReadWrite, parameters.mediaCacheDirectoryExtensionHandle);
841
842     parameters.mediaKeyStorageDirectory = websiteDataStore.resolvedMediaKeysDirectory();
843     if (parameters.mediaKeyStorageDirectory.isEmpty())
844         parameters.mediaKeyStorageDirectory = m_resolvedPaths.mediaKeyStorageDirectory;
845     if (!parameters.mediaKeyStorageDirectory.isEmpty())
846         SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaKeyStorageDirectory, SandboxExtension::Type::ReadWrite, parameters.mediaKeyStorageDirectoryExtensionHandle);
847
848 #if PLATFORM(IOS_FAMILY)
849     setJavaScriptConfigurationFileEnabledFromDefaults();
850 #endif
851
852     if (javaScriptConfigurationFileEnabled()) {
853         parameters.javaScriptConfigurationDirectory = websiteDataStore.resolvedJavaScriptConfigurationDirectory();
854         if (!parameters.javaScriptConfigurationDirectory.isEmpty())
855             SandboxExtension::createHandleWithoutResolvingPath(parameters.javaScriptConfigurationDirectory, SandboxExtension::Type::ReadWrite, parameters.javaScriptConfigurationDirectoryExtensionHandle);
856     }
857
858     parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession;
859
860     parameters.cacheModel = cacheModel();
861     parameters.languages = userPreferredLanguages();
862
863     parameters.urlSchemesRegisteredAsEmptyDocument = copyToVector(m_schemesToRegisterAsEmptyDocument);
864     parameters.urlSchemesRegisteredAsSecure = copyToVector(m_schemesToRegisterAsSecure);
865     parameters.urlSchemesRegisteredAsBypassingContentSecurityPolicy = copyToVector(m_schemesToRegisterAsBypassingContentSecurityPolicy);
866     parameters.urlSchemesForWhichDomainRelaxationIsForbidden = copyToVector(m_schemesToSetDomainRelaxationForbiddenFor);
867     parameters.urlSchemesRegisteredAsLocal = copyToVector(m_schemesToRegisterAsLocal);
868     parameters.urlSchemesRegisteredAsNoAccess = copyToVector(m_schemesToRegisterAsNoAccess);
869     parameters.urlSchemesRegisteredAsDisplayIsolated = copyToVector(m_schemesToRegisterAsDisplayIsolated);
870     parameters.urlSchemesRegisteredAsCORSEnabled = copyToVector(m_schemesToRegisterAsCORSEnabled);
871     parameters.urlSchemesRegisteredAsAlwaysRevalidated = copyToVector(m_schemesToRegisterAsAlwaysRevalidated);
872     parameters.urlSchemesRegisteredAsCachePartitioned = copyToVector(m_schemesToRegisterAsCachePartitioned);
873     parameters.urlSchemesServiceWorkersCanHandle = copyToVector(m_schemesServiceWorkersCanHandle);
874     parameters.urlSchemesRegisteredAsCanDisplayOnlyIfCanRequest = copyToVector(m_schemesToRegisterAsCanDisplayOnlyIfCanRequest);
875
876     parameters.shouldAlwaysUseComplexTextCodePath = m_alwaysUsesComplexTextCodePath;
877     parameters.shouldUseFontSmoothing = m_shouldUseFontSmoothing;
878
879     parameters.terminationTimeout = 0_s;
880
881     parameters.textCheckerState = TextChecker::state();
882
883     parameters.fullKeyboardAccessEnabled = WebProcessProxy::fullKeyboardAccessEnabled();
884
885     parameters.defaultRequestTimeoutInterval = API::URLRequest::defaultTimeoutInterval();
886
887 #if ENABLE(NOTIFICATIONS)
888     // FIXME: There should be a generic way for supplements to add to the intialization parameters.
889     parameters.notificationPermissions = supplement<WebNotificationManagerProxy>()->notificationPermissions();
890 #endif
891
892     parameters.plugInAutoStartOriginHashes = m_plugInAutoStartProvider.autoStartOriginHashesCopy();
893     parameters.plugInAutoStartOrigins = copyToVector(m_plugInAutoStartProvider.autoStartOrigins());
894
895     parameters.memoryCacheDisabled = m_memoryCacheDisabled;
896     parameters.attrStyleEnabled = m_configuration->attrStyleEnabled();
897
898 #if ENABLE(SERVICE_CONTROLS)
899     auto& serviceController = ServicesController::singleton();
900     parameters.hasImageServices = serviceController.hasImageServices();
901     parameters.hasSelectionServices = serviceController.hasSelectionServices();
902     parameters.hasRichContentServices = serviceController.hasRichContentServices();
903     serviceController.refreshExistingServices();
904 #endif
905
906 #if ENABLE(NETSCAPE_PLUGIN_API)
907     parameters.pluginLoadClientPolicies = m_pluginLoadClientPolicies;
908 #endif
909
910 #if OS(LINUX)
911     parameters.shouldEnableMemoryPressureReliefLogging = true;
912 #endif
913
914 #if PLATFORM(WAYLAND) && USE(EGL)
915     if (PlatformDisplay::sharedDisplay().type() == PlatformDisplay::Type::Wayland)
916         parameters.waylandCompositorDisplayName = WaylandCompositor::singleton().displayName();
917 #endif
918
919     parameters.resourceLoadStatisticsEnabled = websiteDataStore.resourceLoadStatisticsEnabled();
920 #if ENABLE(MEDIA_STREAM)
921     parameters.shouldCaptureAudioInUIProcess = m_configuration->shouldCaptureAudioInUIProcess();
922     parameters.shouldCaptureVideoInUIProcess = m_configuration->shouldCaptureVideoInUIProcess();
923     parameters.shouldCaptureDisplayInUIProcess = m_configuration->shouldCaptureDisplayInUIProcess();
924 #endif
925
926     parameters.presentingApplicationPID = m_configuration->presentingApplicationPID();
927
928 #if PLATFORM(COCOA)
929     parameters.mediaMIMETypes = process.mediaMIMETypes();
930 #endif
931
932     // Add any platform specific parameters
933     platformInitializeWebProcess(parameters);
934
935     RefPtr<API::Object> injectedBundleInitializationUserData = m_injectedBundleClient->getInjectedBundleInitializationUserData(*this);
936     if (!injectedBundleInitializationUserData)
937         injectedBundleInitializationUserData = m_injectedBundleInitializationUserData;
938     parameters.initializationUserData = UserData(process.transformObjectsToHandles(injectedBundleInitializationUserData.get()));
939
940     process.send(Messages::WebProcess::InitializeWebProcess(parameters), 0);
941
942 #if PLATFORM(COCOA)
943     process.send(Messages::WebProcess::SetQOS(webProcessLatencyQOS(), webProcessThroughputQOS()), 0);
944 #endif
945
946     if (WebPreferences::anyPagesAreUsingPrivateBrowsing())
947         process.send(Messages::WebProcess::AddWebsiteDataStore(WebsiteDataStoreParameters::legacyPrivateSessionParameters()), 0);
948
949     if (m_automationSession)
950         process.send(Messages::WebProcess::EnsureAutomationSessionProxy(m_automationSession->sessionIdentifier()), 0);
951
952     ASSERT(m_messagesToInjectedBundlePostedToEmptyContext.isEmpty());
953
954 #if ENABLE(REMOTE_INSPECTOR)
955     // Initialize remote inspector connection now that we have a sub-process that is hosting one of our web views.
956     Inspector::RemoteInspector::singleton(); 
957 #endif
958
959 #if PLATFORM(MAC)
960     registerDisplayConfigurationCallback();
961 #endif
962 }
963
964 void WebProcessPool::prewarmProcess(MayCreateDefaultDataStore mayCreateDefaultDataStore)
965 {
966     if (m_prewarmedProcess)
967         return;
968
969     auto* websiteDataStore = m_websiteDataStore ? &m_websiteDataStore->websiteDataStore() : nullptr;
970     if (!websiteDataStore) {
971         if (!m_processes.isEmpty())
972             websiteDataStore = &m_processes.last()->websiteDataStore();
973         else if (mayCreateDefaultDataStore == MayCreateDefaultDataStore::Yes || API::WebsiteDataStore::defaultDataStoreExists())
974             websiteDataStore = &API::WebsiteDataStore::defaultDataStore()->websiteDataStore();
975         else {
976             RELEASE_LOG(PerformanceLogging, "Unable to prewarming a WebProcess because we could not find a usable data store");
977             return;
978         }
979     }
980     ASSERT(websiteDataStore);
981
982     RELEASE_LOG(PerformanceLogging, "Prewarming a WebProcess for performance");
983     createNewWebProcess(*websiteDataStore, WebProcessProxy::IsPrewarmed::Yes);
984 }
985
986 void WebProcessPool::enableProcessTermination()
987 {
988     m_processTerminationEnabled = true;
989     Vector<RefPtr<WebProcessProxy>> processes = m_processes;
990     for (size_t i = 0; i < processes.size(); ++i) {
991         if (shouldTerminate(processes[i].get()))
992             processes[i]->terminate();
993     }
994 }
995
996 bool WebProcessPool::shouldTerminate(WebProcessProxy* process)
997 {
998     ASSERT(m_processes.contains(process));
999
1000     if (!m_processTerminationEnabled || m_configuration->alwaysKeepAndReuseSwappedProcesses())
1001         return false;
1002
1003     return true;
1004 }
1005
1006 void WebProcessPool::processDidFinishLaunching(WebProcessProxy* process)
1007 {
1008     ASSERT(m_processes.contains(process));
1009
1010     if (!m_visitedLinksPopulated) {
1011         populateVisitedLinks();
1012         m_visitedLinksPopulated = true;
1013     }
1014
1015     // Sometimes the memorySampler gets initialized after process initialization has happened but before the process has finished launching
1016     // so check if it needs to be started here
1017     if (m_memorySamplerEnabled) {
1018         SandboxExtension::Handle sampleLogSandboxHandle;        
1019         WallTime now = WallTime::now();
1020         String sampleLogFilePath = String::format("WebProcess%llupid%d", static_cast<unsigned long long>(now.secondsSinceEpoch().seconds()), process->processIdentifier());
1021         sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::Type::ReadWrite, sampleLogSandboxHandle);
1022         
1023         process->send(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, m_memorySamplerInterval), 0);
1024     }
1025
1026     if (m_configuration->fullySynchronousModeIsAllowedForTesting())
1027         process->connection()->allowFullySynchronousModeForTesting();
1028
1029     if (m_configuration->ignoreSynchronousMessagingTimeoutsForTesting())
1030         process->connection()->ignoreTimeoutsForTesting();
1031
1032     m_connectionClient.didCreateConnection(this, process->webConnection());
1033 }
1034
1035 void WebProcessPool::disconnectProcess(WebProcessProxy* process)
1036 {
1037     ASSERT(m_processes.contains(process));
1038
1039     if (m_prewarmedProcess == process) {
1040         ASSERT(m_prewarmedProcess->isPrewarmed());
1041         m_prewarmedProcess = nullptr;
1042     }
1043
1044     // 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.
1045     // Clearing everything causes assertion failures, so it's less trouble to skip that for now.
1046     RefPtr<WebProcessProxy> protect(process);
1047     if (m_processWithPageCache == process)
1048         m_processWithPageCache = nullptr;
1049
1050     m_suspendedPages.removeAllMatching([process](auto& suspendedPage) {
1051         return &suspendedPage->process() == process;
1052     });
1053
1054 #if ENABLE(SERVICE_WORKER)
1055     if (is<ServiceWorkerProcessProxy>(*process)) {
1056         auto* removedProcess = m_serviceWorkerProcesses.take(downcast<ServiceWorkerProcessProxy>(*process).securityOrigin());
1057         ASSERT_UNUSED(removedProcess, removedProcess == process);
1058         updateProcessAssertions();
1059     }
1060 #endif
1061
1062     static_cast<WebContextSupplement*>(supplement<WebGeolocationManagerProxy>())->processDidClose(process);
1063
1064     m_processes.removeFirst(process);
1065
1066 #if ENABLE(GAMEPAD)
1067     if (m_processesUsingGamepads.contains(process))
1068         processStoppedUsingGamepads(*process);
1069 #endif
1070
1071     removeProcessFromOriginCacheSet(*process);
1072
1073 #if ENABLE(SERVICE_WORKER)
1074     // FIXME: We should do better than this. For now, we just destroy the ServiceWorker process
1075     // whenever there is no regular WebContent process remaining.
1076     if (m_processes.size() == m_serviceWorkerProcesses.size()) {
1077         if (!m_serviceWorkerProcessesTerminationTimer.isActive())
1078             m_serviceWorkerProcessesTerminationTimer.startOneShot(serviceWorkerTerminationDelay);
1079     }
1080 #endif
1081 }
1082
1083 WebProcessProxy& WebProcessPool::createNewWebProcessRespectingProcessCountLimit(WebsiteDataStore& websiteDataStore)
1084 {
1085     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=168676
1086     // Once WebsiteDataStores are truly per-view instead of per-process, remove this nonsense.
1087
1088 #if PLATFORM(COCOA)
1089     bool mustMatchDataStore = API::WebsiteDataStore::defaultDataStoreExists() && &websiteDataStore != &API::WebsiteDataStore::defaultDataStore()->websiteDataStore();
1090 #else
1091     bool mustMatchDataStore = false;
1092 #endif
1093
1094     if (m_processes.size() < maximumNumberOfProcesses())
1095         return createNewWebProcess(websiteDataStore);
1096
1097     WebProcessProxy* processToReuse = nullptr;
1098     for (auto& process : m_processes) {
1099         if (mustMatchDataStore && &process->websiteDataStore() != &websiteDataStore)
1100             continue;
1101 #if ENABLE(SERVICE_WORKER)
1102         if (is<ServiceWorkerProcessProxy>(*process))
1103             continue;
1104 #endif
1105         // Choose the process with fewest pages.
1106         if (!processToReuse || processToReuse->pageCount() > process->pageCount())
1107             processToReuse = process.get();
1108     }
1109     return processToReuse ? *processToReuse : createNewWebProcess(websiteDataStore);
1110 }
1111
1112 Ref<WebPageProxy> WebProcessPool::createWebPage(PageClient& pageClient, Ref<API::PageConfiguration>&& pageConfiguration)
1113 {
1114     if (!pageConfiguration->pageGroup())
1115         pageConfiguration->setPageGroup(m_defaultPageGroup.ptr());
1116     if (!pageConfiguration->preferences())
1117         pageConfiguration->setPreferences(&pageConfiguration->pageGroup()->preferences());
1118     if (!pageConfiguration->userContentController())
1119         pageConfiguration->setUserContentController(&pageConfiguration->pageGroup()->userContentController());
1120     if (!pageConfiguration->visitedLinkStore())
1121         pageConfiguration->setVisitedLinkStore(m_visitedLinkStore.ptr());
1122
1123     if (!pageConfiguration->websiteDataStore()) {
1124         // We try to avoid creating the default data store as long as possible.
1125         // But if there is an attempt to create a web page without any specified data store, then we have to create it.
1126         if (!m_websiteDataStore)
1127             m_websiteDataStore = API::WebsiteDataStore::defaultDataStore().ptr();
1128
1129         ASSERT(!pageConfiguration->sessionID().isValid());
1130         pageConfiguration->setWebsiteDataStore(m_websiteDataStore.get());
1131         pageConfiguration->setSessionID(pageConfiguration->preferences()->privateBrowsingEnabled() ? PAL::SessionID::legacyPrivateSessionID() : m_websiteDataStore->websiteDataStore().sessionID());
1132     }
1133
1134     RefPtr<WebProcessProxy> process;
1135     if (pageConfiguration->relatedPage()) {
1136         // Sharing processes, e.g. when creating the page via window.open().
1137         process = &pageConfiguration->relatedPage()->process();
1138     } else {
1139         process = tryTakePrewarmedProcess(pageConfiguration->websiteDataStore()->websiteDataStore());
1140         if (!process)
1141             process = &createNewWebProcessRespectingProcessCountLimit(pageConfiguration->websiteDataStore()->websiteDataStore());
1142     }
1143
1144 #if ENABLE(SERVICE_WORKER)
1145     ASSERT(!is<ServiceWorkerProcessProxy>(*process));
1146 #endif
1147
1148     auto page = process->createWebPage(pageClient, WTFMove(pageConfiguration));
1149     m_configuration->setProcessSwapsOnNavigationFromExperimentalFeatures(page->preferences().processSwapOnCrossSiteNavigationEnabled());
1150     m_configuration->setShouldCaptureAudioInUIProcess(page->preferences().captureAudioInUIProcessEnabled());
1151     m_configuration->setShouldCaptureVideoInUIProcess(page->preferences().captureVideoInUIProcessEnabled());
1152
1153     return page;
1154 }
1155
1156 #if ENABLE(SERVICE_WORKER)
1157 void WebProcessPool::updateServiceWorkerUserAgent(const String& userAgent)
1158 {
1159     if (m_serviceWorkerUserAgent == userAgent)
1160         return;
1161     m_serviceWorkerUserAgent = userAgent;
1162     for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values())
1163         serviceWorkerProcess->setUserAgent(m_serviceWorkerUserAgent);
1164 }
1165
1166 bool WebProcessPool::mayHaveRegisteredServiceWorkers(const WebsiteDataStore& store)
1167 {
1168     if (!m_serviceWorkerProcesses.isEmpty())
1169         return true;
1170
1171     String serviceWorkerRegistrationDirectory = store.resolvedServiceWorkerRegistrationDirectory();
1172     if (serviceWorkerRegistrationDirectory.isEmpty())
1173         serviceWorkerRegistrationDirectory = API::WebsiteDataStore::defaultDataStoreConfiguration()->serviceWorkerRegistrationDirectory();
1174
1175     return m_mayHaveRegisteredServiceWorkers.ensure(serviceWorkerRegistrationDirectory, [&] {
1176         // FIXME: Make this computation on a background thread.
1177         return ServiceWorkerProcessProxy::hasRegisteredServiceWorkers(serviceWorkerRegistrationDirectory);
1178     }).iterator->value;
1179 }
1180 #endif
1181
1182 void WebProcessPool::pageBeginUsingWebsiteDataStore(WebPageProxy& page)
1183 {
1184     auto result = m_sessionToPagesMap.add(page.sessionID(), HashSet<WebPageProxy*>()).iterator->value.add(&page);
1185     ASSERT_UNUSED(result, result.isNewEntry);
1186
1187     auto sessionID = page.sessionID();
1188     if (sessionID.isEphemeral()) {
1189         ASSERT(page.websiteDataStore().parameters().networkSessionParameters.sessionID == sessionID);
1190         if (m_networkProcess)
1191             m_networkProcess->addSession(makeRef(page.websiteDataStore()));
1192         page.process().send(Messages::WebProcess::AddWebsiteDataStore(WebsiteDataStoreParameters::privateSessionParameters(sessionID)), 0);
1193         page.websiteDataStore().clearPendingCookies();
1194     } else if (sessionID != PAL::SessionID::defaultSessionID()) {
1195         if (m_networkProcess)
1196             m_networkProcess->addSession(makeRef(page.websiteDataStore()));
1197         page.process().send(Messages::WebProcess::AddWebsiteDataStore(page.websiteDataStore().parameters()), 0);
1198         page.websiteDataStore().clearPendingCookies();
1199     }
1200
1201 #if ENABLE(SERVICE_WORKER)
1202     if (!m_serviceWorkerPreferences) {
1203         m_serviceWorkerPreferences = page.preferencesStore();
1204         for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values())
1205             serviceWorkerProcess->updatePreferencesStore(*m_serviceWorkerPreferences);
1206     }
1207 #endif
1208 }
1209
1210 void WebProcessPool::pageEndUsingWebsiteDataStore(WebPageProxy& page)
1211 {
1212     auto sessionID = page.sessionID();
1213     auto iterator = m_sessionToPagesMap.find(sessionID);
1214     ASSERT(iterator != m_sessionToPagesMap.end());
1215
1216     auto takenPage = iterator->value.take(&page);
1217     ASSERT_UNUSED(takenPage, takenPage == &page);
1218
1219     if (iterator->value.isEmpty()) {
1220         m_sessionToPagesMap.remove(iterator);
1221
1222         if (sessionID == PAL::SessionID::defaultSessionID())
1223             return;
1224
1225         // The last user of this non-default PAL::SessionID is gone, so clean it up in the child processes.
1226         if (networkProcess())
1227             networkProcess()->removeSession(sessionID);
1228         page.process().send(Messages::WebProcess::DestroySession(sessionID), 0);
1229     }
1230 }
1231
1232 DownloadProxy* WebProcessPool::download(WebPageProxy* initiatingPage, const ResourceRequest& request, const String& suggestedFilename)
1233 {
1234     auto* downloadProxy = createDownloadProxy(request, initiatingPage);
1235     PAL::SessionID sessionID = initiatingPage ? initiatingPage->sessionID() : PAL::SessionID::defaultSessionID();
1236
1237     if (initiatingPage)
1238         initiatingPage->handleDownloadRequest(downloadProxy);
1239
1240     if (networkProcess()) {
1241         ResourceRequest updatedRequest(request);
1242         // Request's firstPartyForCookies will be used as Original URL of the download request.
1243         // We set the value to top level document's URL.
1244         if (initiatingPage) {
1245             URL initiatingPageURL = URL { URL { }, initiatingPage->pageLoadState().url() };
1246             updatedRequest.setFirstPartyForCookies(initiatingPageURL);
1247             updatedRequest.setIsSameSite(registrableDomainsAreEqual(initiatingPageURL, request.url()));
1248             if (!updatedRequest.hasHTTPHeaderField(HTTPHeaderName::UserAgent))
1249                 updatedRequest.setHTTPUserAgent(initiatingPage->userAgent());
1250         } else {
1251             updatedRequest.setFirstPartyForCookies(URL());
1252             updatedRequest.setIsSameSite(false);
1253             if (!updatedRequest.hasHTTPHeaderField(HTTPHeaderName::UserAgent))
1254                 updatedRequest.setHTTPUserAgent(WebPageProxy::standardUserAgent());
1255         }
1256         updatedRequest.setIsTopSite(false);
1257         networkProcess()->send(Messages::NetworkProcess::DownloadRequest(sessionID, downloadProxy->downloadID(), updatedRequest, suggestedFilename), 0);
1258         return downloadProxy;
1259     }
1260
1261     return downloadProxy;
1262 }
1263
1264 DownloadProxy* WebProcessPool::resumeDownload(WebPageProxy* initiatingPage, const API::Data* resumeData, const String& path)
1265 {
1266     auto* downloadProxy = createDownloadProxy(ResourceRequest(), initiatingPage);
1267     PAL::SessionID sessionID = initiatingPage ? initiatingPage->sessionID() : PAL::SessionID::defaultSessionID();
1268
1269     SandboxExtension::Handle sandboxExtensionHandle;
1270     if (!path.isEmpty())
1271         SandboxExtension::createHandle(path, SandboxExtension::Type::ReadWrite, sandboxExtensionHandle);
1272
1273     if (networkProcess()) {
1274         networkProcess()->send(Messages::NetworkProcess::ResumeDownload(sessionID, downloadProxy->downloadID(), resumeData->dataReference(), path, sandboxExtensionHandle), 0);
1275         return downloadProxy;
1276     }
1277
1278     return downloadProxy;
1279 }
1280
1281 void WebProcessPool::postMessageToInjectedBundle(const String& messageName, API::Object* messageBody)
1282 {
1283     for (auto& process : m_processes) {
1284         // FIXME: Return early if the message body contains any references to WKPageRefs/WKFrameRefs etc. since they're local to a process.
1285         process->send(Messages::WebProcess::HandleInjectedBundleMessage(messageName, UserData(process->transformObjectsToHandles(messageBody).get())), 0);
1286     }
1287 }
1288
1289 void WebProcessPool::didReachGoodTimeToPrewarm()
1290 {
1291     if (!configuration().isAutomaticProcessWarmingEnabled() || !configuration().processSwapsOnNavigation())
1292         return;
1293
1294     if (MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
1295         if (!m_prewarmedProcess)
1296             RELEASE_LOG(PerformanceLogging, "Not automatically prewarming a WebProcess due to memory pressure");
1297         return;
1298     }
1299
1300     prewarmProcess(MayCreateDefaultDataStore::No);
1301 }
1302
1303 void WebProcessPool::populateVisitedLinks()
1304 {
1305     m_historyClient->populateVisitedLinks(*this);
1306 }
1307
1308 WebProcessPool::Statistics& WebProcessPool::statistics()
1309 {
1310     static Statistics statistics = Statistics();
1311
1312     return statistics;
1313 }
1314
1315 void WebProcessPool::handleMemoryPressureWarning(Critical)
1316 {
1317     if (m_prewarmedProcess)
1318         m_prewarmedProcess->shutDown();
1319     ASSERT(!m_prewarmedProcess);
1320
1321     m_suspendedPages.clear();
1322 }
1323
1324 #if ENABLE(NETSCAPE_PLUGIN_API)
1325 void WebProcessPool::setAdditionalPluginsDirectory(const String& directory)
1326 {
1327     Vector<String> directories;
1328     directories.append(directory);
1329
1330     m_pluginInfoStore.setAdditionalPluginsDirectories(directories);
1331 }
1332
1333 void WebProcessPool::refreshPlugins()
1334 {
1335     m_pluginInfoStore.refresh();
1336     sendToAllProcesses(Messages::WebProcess::RefreshPlugins());
1337 }
1338
1339 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1340
1341 ProcessID WebProcessPool::networkProcessIdentifier()
1342 {
1343     if (!m_networkProcess)
1344         return 0;
1345
1346     return m_networkProcess->processIdentifier();
1347 }
1348
1349 void WebProcessPool::activePagesOriginsInWebProcessForTesting(ProcessID pid, CompletionHandler<void(Vector<String>&&)>&& completionHandler)
1350 {
1351     for (auto& process : m_processes) {
1352         if (process->processIdentifier() == pid)
1353             return process->activePagesDomainsForTesting(WTFMove(completionHandler));
1354     }
1355     completionHandler({ });
1356 }
1357
1358 void WebProcessPool::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
1359 {
1360     m_alwaysUsesComplexTextCodePath = alwaysUseComplexText;
1361     sendToAllProcesses(Messages::WebProcess::SetAlwaysUsesComplexTextCodePath(alwaysUseComplexText));
1362 }
1363
1364 void WebProcessPool::setShouldUseFontSmoothing(bool useFontSmoothing)
1365 {
1366     m_shouldUseFontSmoothing = useFontSmoothing;
1367     sendToAllProcesses(Messages::WebProcess::SetShouldUseFontSmoothing(useFontSmoothing));
1368 }
1369
1370 void WebProcessPool::setResourceLoadStatisticsEnabled(bool enabled)
1371 {
1372     sendToAllProcesses(Messages::WebProcess::SetResourceLoadStatisticsEnabled(enabled));
1373 }
1374
1375 void WebProcessPool::clearResourceLoadStatistics()
1376 {
1377     sendToAllProcesses(Messages::WebProcess::ClearResourceLoadStatistics());
1378 }
1379
1380 void WebProcessPool::registerURLSchemeAsEmptyDocument(const String& urlScheme)
1381 {
1382     m_schemesToRegisterAsEmptyDocument.add(urlScheme);
1383     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsEmptyDocument(urlScheme));
1384 }
1385
1386 void WebProcessPool::registerURLSchemeAsSecure(const String& urlScheme)
1387 {
1388     m_schemesToRegisterAsSecure.add(urlScheme);
1389     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsSecure(urlScheme));
1390     sendToNetworkingProcess(Messages::NetworkProcess::RegisterURLSchemeAsSecure(urlScheme));
1391 }
1392
1393 void WebProcessPool::registerURLSchemeAsBypassingContentSecurityPolicy(const String& urlScheme)
1394 {
1395     m_schemesToRegisterAsBypassingContentSecurityPolicy.add(urlScheme);
1396     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsBypassingContentSecurityPolicy(urlScheme));
1397     sendToNetworkingProcess(Messages::NetworkProcess::RegisterURLSchemeAsBypassingContentSecurityPolicy(urlScheme));
1398 }
1399
1400 void WebProcessPool::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme)
1401 {
1402     m_schemesToSetDomainRelaxationForbiddenFor.add(urlScheme);
1403     sendToAllProcesses(Messages::WebProcess::SetDomainRelaxationForbiddenForURLScheme(urlScheme));
1404 }
1405
1406 void WebProcessPool::setCanHandleHTTPSServerTrustEvaluation(bool value)
1407 {
1408     m_canHandleHTTPSServerTrustEvaluation = value;
1409     if (m_networkProcess) {
1410         m_networkProcess->send(Messages::NetworkProcess::SetCanHandleHTTPSServerTrustEvaluation(value), 0);
1411         return;
1412     }
1413 }
1414
1415 void WebProcessPool::preconnectToServer(const URL& url)
1416 {
1417     if (!url.isValid() || !url.protocolIsInHTTPFamily())
1418         return;
1419
1420     ensureNetworkProcess().send(Messages::NetworkProcess::PreconnectTo(url, StoredCredentialsPolicy::Use), 0);
1421 }
1422
1423 void WebProcessPool::registerURLSchemeAsLocal(const String& urlScheme)
1424 {
1425     m_schemesToRegisterAsLocal.add(urlScheme);
1426     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsLocal(urlScheme));
1427     sendToNetworkingProcess(Messages::NetworkProcess::RegisterURLSchemeAsLocal(urlScheme));
1428 }
1429
1430 void WebProcessPool::registerURLSchemeAsNoAccess(const String& urlScheme)
1431 {
1432     m_schemesToRegisterAsNoAccess.add(urlScheme);
1433     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsNoAccess(urlScheme));
1434     sendToNetworkingProcess(Messages::NetworkProcess::RegisterURLSchemeAsNoAccess(urlScheme));
1435 }
1436
1437 void WebProcessPool::registerURLSchemeAsDisplayIsolated(const String& urlScheme)
1438 {
1439     m_schemesToRegisterAsDisplayIsolated.add(urlScheme);
1440     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsDisplayIsolated(urlScheme));
1441     sendToNetworkingProcess(Messages::NetworkProcess::RegisterURLSchemeAsDisplayIsolated(urlScheme));
1442 }
1443
1444 void WebProcessPool::registerURLSchemeAsCORSEnabled(const String& urlScheme)
1445 {
1446     m_schemesToRegisterAsCORSEnabled.add(urlScheme);
1447     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsCORSEnabled(urlScheme));
1448     sendToNetworkingProcess(Messages::NetworkProcess::RegisterURLSchemeAsCORSEnabled(urlScheme));
1449 }
1450
1451 void WebProcessPool::registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme)
1452 {
1453     if (!urlScheme)
1454         return;
1455
1456     globalURLSchemesWithCustomProtocolHandlers().add(urlScheme);
1457     for (auto* processPool : allProcessPools())
1458         processPool->registerSchemeForCustomProtocol(urlScheme);
1459 }
1460
1461 void WebProcessPool::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme)
1462 {
1463     if (!urlScheme)
1464         return;
1465
1466     globalURLSchemesWithCustomProtocolHandlers().remove(urlScheme);
1467     for (auto* processPool : allProcessPools())
1468         processPool->unregisterSchemeForCustomProtocol(urlScheme);
1469 }
1470
1471 void WebProcessPool::registerURLSchemeAsCachePartitioned(const String& urlScheme)
1472 {
1473     m_schemesToRegisterAsCachePartitioned.add(urlScheme);
1474     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsCachePartitioned(urlScheme));
1475 }
1476
1477 void WebProcessPool::registerURLSchemeServiceWorkersCanHandle(const String& urlScheme)
1478 {
1479     m_schemesServiceWorkersCanHandle.add(urlScheme);
1480     sendToAllProcesses(Messages::ChildProcess::RegisterURLSchemeServiceWorkersCanHandle(urlScheme));
1481     if (m_networkProcess)
1482         m_networkProcess->send(Messages::ChildProcess::RegisterURLSchemeServiceWorkersCanHandle(urlScheme), 0);
1483 }
1484
1485 void WebProcessPool::registerURLSchemeAsCanDisplayOnlyIfCanRequest(const String& urlScheme)
1486 {
1487     m_schemesToRegisterAsCanDisplayOnlyIfCanRequest.add(urlScheme);
1488     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsCanDisplayOnlyIfCanRequest(urlScheme));
1489     sendToNetworkingProcess(Messages::NetworkProcess::RegisterURLSchemeAsCanDisplayOnlyIfCanRequest(urlScheme));
1490 }
1491
1492 void WebProcessPool::updateMaxSuspendedPageCount()
1493 {
1494     unsigned dummy = 0;
1495     Seconds dummyInterval;
1496     unsigned pageCacheSize = 0;
1497     calculateMemoryCacheSizes(m_configuration->cacheModel(), dummy, dummy, dummy, dummyInterval, pageCacheSize);
1498
1499     m_maxSuspendedPageCount = pageCacheSize;
1500
1501     while (m_suspendedPages.size() > m_maxSuspendedPageCount)
1502         m_suspendedPages.removeFirst();
1503 }
1504
1505 void WebProcessPool::setCacheModel(CacheModel cacheModel)
1506 {
1507     m_configuration->setCacheModel(cacheModel);
1508     updateMaxSuspendedPageCount();
1509
1510     sendToAllProcesses(Messages::WebProcess::SetCacheModel(cacheModel));
1511
1512     if (m_networkProcess)
1513         m_networkProcess->send(Messages::NetworkProcess::SetCacheModel(cacheModel), 0);
1514 }
1515
1516 void WebProcessPool::setDefaultRequestTimeoutInterval(double timeoutInterval)
1517 {
1518     sendToAllProcesses(Messages::WebProcess::SetDefaultRequestTimeoutInterval(timeoutInterval));
1519 }
1520
1521 DownloadProxy* WebProcessPool::createDownloadProxy(const ResourceRequest& request, WebPageProxy* originatingPage)
1522 {
1523     auto downloadProxy = ensureNetworkProcess().createDownloadProxy(request);
1524     downloadProxy->setOriginatingPage(originatingPage);
1525     return downloadProxy;
1526 }
1527
1528 void WebProcessPool::addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver& messageReceiver)
1529 {
1530     m_messageReceiverMap.addMessageReceiver(messageReceiverName, messageReceiver);
1531 }
1532
1533 void WebProcessPool::addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver& messageReceiver)
1534 {
1535     m_messageReceiverMap.addMessageReceiver(messageReceiverName, destinationID, messageReceiver);
1536 }
1537
1538 void WebProcessPool::removeMessageReceiver(IPC::StringReference messageReceiverName)
1539 {
1540     m_messageReceiverMap.removeMessageReceiver(messageReceiverName);
1541 }
1542
1543 void WebProcessPool::removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID)
1544 {
1545     m_messageReceiverMap.removeMessageReceiver(messageReceiverName, destinationID);
1546 }
1547
1548 bool WebProcessPool::dispatchMessage(IPC::Connection& connection, IPC::Decoder& decoder)
1549 {
1550     return m_messageReceiverMap.dispatchMessage(connection, decoder);
1551 }
1552
1553 bool WebProcessPool::dispatchSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
1554 {
1555     return m_messageReceiverMap.dispatchSyncMessage(connection, decoder, replyEncoder);
1556 }
1557
1558 void WebProcessPool::setEnhancedAccessibility(bool flag)
1559 {
1560     sendToAllProcesses(Messages::WebProcess::SetEnhancedAccessibility(flag));
1561 }
1562     
1563 void WebProcessPool::startMemorySampler(const double interval)
1564 {    
1565     // For new WebProcesses we will also want to start the Memory Sampler
1566     m_memorySamplerEnabled = true;
1567     m_memorySamplerInterval = interval;
1568     
1569     // For UIProcess
1570 #if ENABLE(MEMORY_SAMPLER)
1571     WebMemorySampler::singleton()->start(interval);
1572 #endif
1573     
1574     // For WebProcess
1575     SandboxExtension::Handle sampleLogSandboxHandle;    
1576     WallTime now = WallTime::now();
1577     String sampleLogFilePath = String::format("WebProcess%llu", static_cast<unsigned long long>(now.secondsSinceEpoch().seconds()));
1578     sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::Type::ReadWrite, sampleLogSandboxHandle);
1579     
1580     sendToAllProcesses(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, interval));
1581 }
1582
1583 void WebProcessPool::stopMemorySampler()
1584 {    
1585     // For WebProcess
1586     m_memorySamplerEnabled = false;
1587     
1588     // For UIProcess
1589 #if ENABLE(MEMORY_SAMPLER)
1590     WebMemorySampler::singleton()->stop();
1591 #endif
1592
1593     sendToAllProcesses(Messages::WebProcess::StopMemorySampler());
1594 }
1595
1596 void WebProcessPool::useTestingNetworkSession()
1597 {
1598     ASSERT(m_processes.isEmpty());
1599     ASSERT(!m_networkProcess);
1600
1601     if (m_networkProcess)
1602         return;
1603
1604     if (!m_processes.isEmpty())
1605         return;
1606
1607     m_shouldUseTestingNetworkSession = true;
1608 }
1609
1610 template<typename T, typename U>
1611 void WebProcessPool::sendSyncToNetworkingProcess(T&& message, U&& reply)
1612 {
1613     if (m_networkProcess && m_networkProcess->canSendMessage())
1614         m_networkProcess->sendSync(std::forward<T>(message), std::forward<U>(reply), 0);
1615 }
1616
1617 void WebProcessPool::setAllowsAnySSLCertificateForWebSocket(bool allows)
1618 {
1619     sendSyncToNetworkingProcess(Messages::NetworkProcess::SetAllowsAnySSLCertificateForWebSocket(allows), Messages::NetworkProcess::SetAllowsAnySSLCertificateForWebSocket::Reply());
1620 }
1621
1622 void WebProcessPool::clearCachedCredentials()
1623 {
1624     sendToAllProcesses(Messages::WebProcess::ClearCachedCredentials());
1625     if (m_networkProcess)
1626         m_networkProcess->send(Messages::NetworkProcess::ClearCachedCredentials(), 0);
1627 }
1628
1629 void WebProcessPool::terminateNetworkProcess()
1630 {
1631     if (!m_networkProcess)
1632         return;
1633     
1634     m_networkProcess->terminate();
1635     m_networkProcess = nullptr;
1636     m_didNetworkProcessCrash = true;
1637 }
1638
1639 void WebProcessPool::terminateServiceWorkerProcesses()
1640 {
1641 #if ENABLE(SERVICE_WORKER)
1642     auto protectedThis = makeRef(*this);
1643     while (!m_serviceWorkerProcesses.isEmpty())
1644         m_serviceWorkerProcesses.begin()->value->requestTermination(ProcessTerminationReason::RequestedByClient);
1645 #endif
1646 }
1647
1648 void WebProcessPool::syncNetworkProcessCookies()
1649 {
1650     ensureNetworkProcess().syncAllCookies();
1651 }
1652
1653 void WebProcessPool::setIDBPerOriginQuota(uint64_t quota)
1654 {
1655 #if ENABLE(INDEXED_DATABASE)
1656     ensureNetworkProcess().send(Messages::NetworkProcess::SetIDBPerOriginQuota(quota), 0);
1657 #endif
1658 }
1659
1660 void WebProcessPool::allowSpecificHTTPSCertificateForHost(const WebCertificateInfo* certificate, const String& host)
1661 {
1662     ensureNetworkProcess();
1663     m_networkProcess->send(Messages::NetworkProcess::AllowSpecificHTTPSCertificateForHost(certificate->certificateInfo(), host), 0);
1664 }
1665
1666 void WebProcessPool::updateAutomationCapabilities() const
1667 {
1668 #if ENABLE(REMOTE_INSPECTOR)
1669     Inspector::RemoteInspector::singleton().clientCapabilitiesDidChange();
1670 #endif
1671 }
1672
1673 void WebProcessPool::setAutomationSession(RefPtr<WebAutomationSession>&& automationSession)
1674 {
1675     if (m_automationSession)
1676         m_automationSession->setProcessPool(nullptr);
1677     
1678     m_automationSession = WTFMove(automationSession);
1679
1680 #if ENABLE(REMOTE_INSPECTOR)
1681     if (m_automationSession) {
1682         m_automationSession->init();
1683         m_automationSession->setProcessPool(this);
1684
1685         sendToAllProcesses(Messages::WebProcess::EnsureAutomationSessionProxy(m_automationSession->sessionIdentifier()));
1686     } else
1687         sendToAllProcesses(Messages::WebProcess::DestroyAutomationSessionProxy());
1688 #endif
1689 }
1690
1691 void WebProcessPool::setHTTPPipeliningEnabled(bool enabled)
1692 {
1693 #if PLATFORM(COCOA)
1694     ResourceRequest::setHTTPPipeliningEnabled(enabled);
1695 #else
1696     UNUSED_PARAM(enabled);
1697 #endif
1698 }
1699
1700 bool WebProcessPool::httpPipeliningEnabled() const
1701 {
1702 #if PLATFORM(COCOA)
1703     return ResourceRequest::httpPipeliningEnabled();
1704 #else
1705     return false;
1706 #endif
1707 }
1708
1709 void WebProcessPool::getStatistics(uint32_t statisticsMask, Function<void (API::Dictionary*, CallbackBase::Error)>&& callbackFunction)
1710 {
1711     if (!statisticsMask) {
1712         callbackFunction(nullptr, CallbackBase::Error::Unknown);
1713         return;
1714     }
1715
1716     RefPtr<StatisticsRequest> request = StatisticsRequest::create(DictionaryCallback::create(WTFMove(callbackFunction)));
1717
1718     if (statisticsMask & StatisticsRequestTypeWebContent)
1719         requestWebContentStatistics(request.get());
1720     
1721     if (statisticsMask & StatisticsRequestTypeNetworking)
1722         requestNetworkingStatistics(request.get());
1723 }
1724
1725 void WebProcessPool::requestWebContentStatistics(StatisticsRequest* request)
1726 {
1727     // FIXME (Multi-WebProcess) <rdar://problem/13200059>: Make getting statistics from multiple WebProcesses work.
1728 }
1729
1730 void WebProcessPool::requestNetworkingStatistics(StatisticsRequest* request)
1731 {
1732     if (!m_networkProcess) {
1733         LOG_ERROR("Attempt to get NetworkProcess statistics but the NetworkProcess is unavailable");
1734         return;
1735     }
1736
1737     uint64_t requestID = request->addOutstandingRequest();
1738     m_statisticsRequests.set(requestID, request);
1739     m_networkProcess->send(Messages::NetworkProcess::GetNetworkProcessStatistics(requestID), 0);
1740 }
1741
1742 static WebProcessProxy* webProcessProxyFromConnection(IPC::Connection& connection, const Vector<RefPtr<WebProcessProxy>>& processes)
1743 {
1744     for (auto& process : processes) {
1745         if (process->hasConnection(connection))
1746             return process.get();
1747     }
1748
1749     ASSERT_NOT_REACHED();
1750     return nullptr;
1751 }
1752
1753 void WebProcessPool::handleMessage(IPC::Connection& connection, const String& messageName, const WebKit::UserData& messageBody)
1754 {
1755     auto* webProcessProxy = webProcessProxyFromConnection(connection, m_processes);
1756     if (!webProcessProxy)
1757         return;
1758     m_injectedBundleClient->didReceiveMessageFromInjectedBundle(*this, messageName, webProcessProxy->transformHandlesToObjects(messageBody.object()).get());
1759 }
1760
1761 void WebProcessPool::handleSynchronousMessage(IPC::Connection& connection, const String& messageName, const UserData& messageBody, UserData& returnUserData)
1762 {
1763     auto* webProcessProxy = webProcessProxyFromConnection(connection, m_processes);
1764     if (!webProcessProxy)
1765         return;
1766
1767     RefPtr<API::Object> returnData;
1768     m_injectedBundleClient->didReceiveSynchronousMessageFromInjectedBundle(*this, messageName, webProcessProxy->transformHandlesToObjects(messageBody.object()).get(), returnData);
1769     returnUserData = UserData(webProcessProxy->transformObjectsToHandles(returnData.get()));
1770 }
1771
1772 void WebProcessPool::didGetStatistics(const StatisticsData& statisticsData, uint64_t requestID)
1773 {
1774     RefPtr<StatisticsRequest> request = m_statisticsRequests.take(requestID);
1775     if (!request) {
1776         LOG_ERROR("Cannot report networking statistics.");
1777         return;
1778     }
1779
1780     request->completedRequest(requestID, statisticsData);
1781 }
1782
1783 #if ENABLE(GAMEPAD)
1784
1785 void WebProcessPool::startedUsingGamepads(IPC::Connection& connection)
1786 {
1787     auto* proxy = webProcessProxyFromConnection(connection, m_processes);
1788     if (!proxy)
1789         return;
1790
1791     bool wereAnyProcessesUsingGamepads = !m_processesUsingGamepads.isEmpty();
1792
1793     ASSERT(!m_processesUsingGamepads.contains(proxy));
1794     m_processesUsingGamepads.add(proxy);
1795
1796     if (!wereAnyProcessesUsingGamepads)
1797         UIGamepadProvider::singleton().processPoolStartedUsingGamepads(*this);
1798
1799     proxy->send(Messages::WebProcess::SetInitialGamepads(UIGamepadProvider::singleton().snapshotGamepads()), 0);
1800 }
1801
1802 void WebProcessPool::stoppedUsingGamepads(IPC::Connection& connection)
1803 {
1804     auto* proxy = webProcessProxyFromConnection(connection, m_processes);
1805     if (!proxy)
1806         return;
1807
1808     ASSERT(m_processesUsingGamepads.contains(proxy));
1809     processStoppedUsingGamepads(*proxy);
1810 }
1811
1812 void WebProcessPool::processStoppedUsingGamepads(WebProcessProxy& process)
1813 {
1814     bool wereAnyProcessesUsingGamepads = !m_processesUsingGamepads.isEmpty();
1815
1816     ASSERT(m_processesUsingGamepads.contains(&process));
1817     m_processesUsingGamepads.remove(&process);
1818
1819     if (wereAnyProcessesUsingGamepads && m_processesUsingGamepads.isEmpty())
1820         UIGamepadProvider::singleton().processPoolStoppedUsingGamepads(*this);
1821 }
1822
1823 void WebProcessPool::gamepadConnected(const UIGamepad& gamepad)
1824 {
1825     for (auto& process : m_processesUsingGamepads)
1826         process->send(Messages::WebProcess::GamepadConnected(gamepad.fullGamepadData()), 0);
1827 }
1828
1829 void WebProcessPool::gamepadDisconnected(const UIGamepad& gamepad)
1830 {
1831     for (auto& process : m_processesUsingGamepads)
1832         process->send(Messages::WebProcess::GamepadDisconnected(gamepad.index()), 0);
1833 }
1834
1835 void WebProcessPool::setInitialConnectedGamepads(const Vector<std::unique_ptr<UIGamepad>>& gamepads)
1836 {
1837     Vector<GamepadData> gamepadDatas;
1838     gamepadDatas.grow(gamepads.size());
1839     for (size_t i = 0; i < gamepads.size(); ++i) {
1840         if (!gamepads[i])
1841             continue;
1842         gamepadDatas[i] = gamepads[i]->fullGamepadData();
1843     }
1844
1845     for (auto& process : m_processesUsingGamepads)
1846         process->send(Messages::WebProcess::SetInitialGamepads(gamepadDatas), 0);
1847 }
1848
1849 #endif // ENABLE(GAMEPAD)
1850
1851 void WebProcessPool::setJavaScriptConfigurationFileEnabled(bool flag)
1852 {
1853     m_javaScriptConfigurationFileEnabled = flag;
1854 }
1855
1856 void WebProcessPool::garbageCollectJavaScriptObjects()
1857 {
1858     sendToAllProcesses(Messages::WebProcess::GarbageCollectJavaScriptObjects());
1859 }
1860
1861 void WebProcessPool::setJavaScriptGarbageCollectorTimerEnabled(bool flag)
1862 {
1863     sendToAllProcesses(Messages::WebProcess::SetJavaScriptGarbageCollectorTimerEnabled(flag));
1864 }
1865
1866 void WebProcessPool::addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, PAL::SessionID sessionID)
1867 {
1868     m_plugInAutoStartProvider.addAutoStartOriginHash(pageOrigin, plugInOriginHash, sessionID);
1869 }
1870
1871 void WebProcessPool::plugInDidReceiveUserInteraction(unsigned plugInOriginHash, PAL::SessionID sessionID)
1872 {
1873     m_plugInAutoStartProvider.didReceiveUserInteraction(plugInOriginHash, sessionID);
1874 }
1875
1876 Ref<API::Dictionary> WebProcessPool::plugInAutoStartOriginHashes() const
1877 {
1878     return m_plugInAutoStartProvider.autoStartOriginsTableCopy();
1879 }
1880
1881 void WebProcessPool::setPlugInAutoStartOriginHashes(API::Dictionary& dictionary)
1882 {
1883     m_plugInAutoStartProvider.setAutoStartOriginsTable(dictionary);
1884 }
1885
1886 void WebProcessPool::setPlugInAutoStartOrigins(API::Array& array)
1887 {
1888     m_plugInAutoStartProvider.setAutoStartOriginsArray(array);
1889 }
1890
1891 void WebProcessPool::setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary& dictionary, WallTime time)
1892 {
1893     m_plugInAutoStartProvider.setAutoStartOriginsFilteringOutEntriesAddedAfterTime(dictionary, time);
1894 }
1895
1896 void WebProcessPool::registerSchemeForCustomProtocol(const String& scheme)
1897 {
1898 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
1899     if (!globalURLSchemesWithCustomProtocolHandlers().contains(scheme))
1900         m_urlSchemesRegisteredForCustomProtocols.add(scheme);
1901     sendToNetworkingProcess(Messages::LegacyCustomProtocolManager::RegisterScheme(scheme));
1902 #endif
1903 }
1904
1905 void WebProcessPool::unregisterSchemeForCustomProtocol(const String& scheme)
1906 {
1907 #if ENABLE(LEGACY_CUSTOM_PROTOCOL_MANAGER)
1908     m_urlSchemesRegisteredForCustomProtocols.remove(scheme);
1909     sendToNetworkingProcess(Messages::LegacyCustomProtocolManager::UnregisterScheme(scheme));
1910 #endif
1911 }
1912
1913 #if ENABLE(NETSCAPE_PLUGIN_API)
1914 void WebProcessPool::setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy policy, const String& host, const String& bundleIdentifier, const String& versionString)
1915 {
1916     auto& policiesForHost = m_pluginLoadClientPolicies.ensure(host, [] { return HashMap<String, HashMap<String, uint8_t>>(); }).iterator->value;
1917     auto& versionsToPolicies = policiesForHost.ensure(bundleIdentifier, [] { return HashMap<String, uint8_t>(); }).iterator->value;
1918     versionsToPolicies.set(versionString, policy);
1919
1920     sendToAllProcesses(Messages::WebProcess::SetPluginLoadClientPolicy(policy, host, bundleIdentifier, versionString));
1921 }
1922
1923 void WebProcessPool::resetPluginLoadClientPolicies(HashMap<String, HashMap<String, HashMap<String, uint8_t>>>&& pluginLoadClientPolicies)
1924 {
1925     m_pluginLoadClientPolicies = WTFMove(pluginLoadClientPolicies);
1926     sendToAllProcesses(Messages::WebProcess::ResetPluginLoadClientPolicies(m_pluginLoadClientPolicies));
1927 }
1928
1929 void WebProcessPool::clearPluginClientPolicies()
1930 {
1931     m_pluginLoadClientPolicies.clear();
1932     sendToAllProcesses(Messages::WebProcess::ClearPluginClientPolicies());
1933 }
1934 #endif
1935
1936 void WebProcessPool::addSupportedPlugin(String&& matchingDomain, String&& name, HashSet<String>&& mimeTypes, HashSet<String> extensions)
1937 {
1938 #if ENABLE(NETSCAPE_PLUGIN_API)
1939     m_pluginInfoStore.addSupportedPlugin(WTFMove(matchingDomain), WTFMove(name), WTFMove(mimeTypes), WTFMove(extensions));
1940 #else
1941     UNUSED_PARAM(matchingDomain);
1942     UNUSED_PARAM(name);
1943     UNUSED_PARAM(mimeTypes);
1944     UNUSED_PARAM(extensions);
1945 #endif
1946 }
1947
1948 void WebProcessPool::clearSupportedPlugins()
1949 {
1950 #if ENABLE(NETSCAPE_PLUGIN_API)
1951     m_pluginInfoStore.clearSupportedPlugins();
1952 #endif
1953 }
1954
1955 void WebProcessPool::setMemoryCacheDisabled(bool disabled)
1956 {
1957     m_memoryCacheDisabled = disabled;
1958     sendToAllProcesses(Messages::WebProcess::SetMemoryCacheDisabled(disabled));
1959 }
1960
1961 void WebProcessPool::setFontWhitelist(API::Array* array)
1962 {
1963     m_fontWhitelist.clear();
1964     if (array) {
1965         for (size_t i = 0; i < array->size(); ++i) {
1966             if (API::String* font = array->at<API::String>(i))
1967                 m_fontWhitelist.append(font->string());
1968         }
1969     }
1970 }
1971
1972 void WebProcessPool::updateHiddenPageThrottlingAutoIncreaseLimit()
1973 {
1974     // We're estimating an upper bound for a set of background timer fires for a page to be 200ms
1975     // (including all timer fires, all paging-in, and any resulting GC). To ensure this does not
1976     // result in more than 1% CPU load allow for one timer fire per 100x this duration.
1977     static int maximumTimerThrottlePerPageInMS = 200 * 100;
1978
1979     int limitInMilliseconds = maximumTimerThrottlePerPageInMS * m_hiddenPageThrottlingAutoIncreasesCounter.value();
1980     sendToAllProcesses(Messages::WebProcess::SetHiddenPageDOMTimerThrottlingIncreaseLimit(limitInMilliseconds));
1981 }
1982
1983 void WebProcessPool::reportWebContentCPUTime(Seconds cpuTime, uint64_t activityState)
1984 {
1985 #if PLATFORM(MAC)
1986     if (m_perActivityStateCPUUsageSampler)
1987         m_perActivityStateCPUUsageSampler->reportWebContentCPUTime(cpuTime, static_cast<WebCore::ActivityStateForCPUSampling>(activityState));
1988 #else
1989     UNUSED_PARAM(cpuTime);
1990     UNUSED_PARAM(activityState);
1991 #endif
1992 }
1993
1994 void WebProcessPool::updateProcessAssertions()
1995 {
1996 #if PLATFORM(IOS_FAMILY)
1997 #if ENABLE(SERVICE_WORKER)
1998     auto updateServiceWorkerProcessAssertion = [&] {
1999         if (!m_serviceWorkerProcesses.isEmpty() && m_foregroundWebProcessCounter.value()) {
2000             // FIXME: We can do better than this once we have process per origin.
2001             for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values()) {
2002                 auto& securityOrigin = serviceWorkerProcess->securityOrigin();
2003                 if (!m_foregroundTokensForServiceWorkerProcesses.contains(securityOrigin))
2004                     m_foregroundTokensForServiceWorkerProcesses.add(securityOrigin, serviceWorkerProcess->throttler().foregroundActivityToken());
2005             }
2006             m_backgroundTokensForServiceWorkerProcesses.clear();
2007             return;
2008         }
2009         if (!m_serviceWorkerProcesses.isEmpty() && m_backgroundWebProcessCounter.value()) {
2010             // FIXME: We can do better than this once we have process per origin.
2011             for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values()) {
2012                 auto& securityOrigin = serviceWorkerProcess->securityOrigin();
2013                 if (!m_backgroundTokensForServiceWorkerProcesses.contains(securityOrigin))
2014                     m_backgroundTokensForServiceWorkerProcesses.add(securityOrigin, serviceWorkerProcess->throttler().backgroundActivityToken());
2015             }
2016             m_foregroundTokensForServiceWorkerProcesses.clear();
2017             return;
2018         }
2019         m_foregroundTokensForServiceWorkerProcesses.clear();
2020         m_backgroundTokensForServiceWorkerProcesses.clear();
2021     };
2022     updateServiceWorkerProcessAssertion();
2023 #endif
2024
2025     auto updateNetworkProcessAssertion = [&] {
2026         auto& networkProcess = ensureNetworkProcess();
2027
2028         if (m_foregroundWebProcessCounter.value()) {
2029             if (!m_foregroundTokenForNetworkProcess) {
2030                 m_foregroundTokenForNetworkProcess = networkProcess.throttler().foregroundActivityToken();
2031                 networkProcess.sendProcessDidTransitionToForeground();
2032             }
2033             m_backgroundTokenForNetworkProcess = nullptr;
2034             return;
2035         }
2036         if (m_backgroundWebProcessCounter.value()) {
2037             if (!m_backgroundTokenForNetworkProcess) {
2038                 m_backgroundTokenForNetworkProcess = networkProcess.throttler().backgroundActivityToken();
2039                 networkProcess.sendProcessDidTransitionToBackground();
2040             }
2041             m_foregroundTokenForNetworkProcess = nullptr;
2042             return;
2043         }
2044         m_foregroundTokenForNetworkProcess = nullptr;
2045         m_backgroundTokenForNetworkProcess = nullptr;
2046     };
2047     updateNetworkProcessAssertion();
2048 #endif
2049 }
2050
2051 #if ENABLE(SERVICE_WORKER)
2052 void WebProcessPool::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destination, MessageWithMessagePorts&& message, ServiceWorkerIdentifier source, const String& sourceOrigin)
2053 {
2054     sendToNetworkingProcessRelaunchingIfNecessary(Messages::NetworkProcess::PostMessageToServiceWorkerClient(destination, WTFMove(message), source, sourceOrigin));
2055 }
2056
2057 void WebProcessPool::postMessageToServiceWorker(ServiceWorkerIdentifier destination, MessageWithMessagePorts&& message, const ServiceWorkerOrClientIdentifier& source, SWServerConnectionIdentifier connectionIdentifier)
2058 {
2059     sendToNetworkingProcessRelaunchingIfNecessary(Messages::NetworkProcess::PostMessageToServiceWorker(destination, WTFMove(message), source, connectionIdentifier));
2060 }
2061 #endif
2062
2063 void WebProcessPool::reinstateNetworkProcessAssertionState(NetworkProcessProxy& newNetworkProcessProxy)
2064 {
2065 #if PLATFORM(IOS_FAMILY)
2066     // The network process crashed; take new tokens for the new network process.
2067     if (m_backgroundTokenForNetworkProcess)
2068         m_backgroundTokenForNetworkProcess = newNetworkProcessProxy.throttler().backgroundActivityToken();
2069     else if (m_foregroundTokenForNetworkProcess)
2070         m_foregroundTokenForNetworkProcess = newNetworkProcessProxy.throttler().foregroundActivityToken();
2071 #else
2072     UNUSED_PARAM(newNetworkProcessProxy);
2073 #endif
2074 }
2075
2076 #if ENABLE(SERVICE_WORKER)
2077 ServiceWorkerProcessProxy* WebProcessPool::serviceWorkerProcessProxyFromPageID(uint64_t pageID) const
2078 {
2079     // FIXME: This is inefficient.
2080     for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values()) {
2081         if (serviceWorkerProcess->pageID() == pageID)
2082             return serviceWorkerProcess;
2083     }
2084     return nullptr;
2085 }
2086 #endif
2087
2088 void WebProcessPool::addProcessToOriginCacheSet(WebPageProxy& page)
2089 {
2090     auto registrableDomain = toRegistrableDomain({ { }, page.pageLoadState().url() });
2091     auto result = m_swappedProcessesPerRegistrableDomain.add(registrableDomain, &page.process());
2092     if (!result.isNewEntry)
2093         result.iterator->value = &page.process();
2094
2095     LOG(ProcessSwapping, "(ProcessSwapping) Registrable domain %s just saved a cached process with pid %i", registrableDomain.utf8().data(), page.process().processIdentifier());
2096     if (!result.isNewEntry)
2097         LOG(ProcessSwapping, "(ProcessSwapping) Note: It already had one saved");
2098 }
2099
2100 void WebProcessPool::removeProcessFromOriginCacheSet(WebProcessProxy& process)
2101 {
2102     LOG(ProcessSwapping, "(ProcessSwapping) Removing process with pid %i from the origin cache set", process.processIdentifier());
2103
2104     // FIXME: This can be very inefficient as the number of remembered origins and processes grows
2105     Vector<String> registrableDomainsToRemove;
2106     for (auto entry : m_swappedProcessesPerRegistrableDomain) {
2107         if (entry.value == &process)
2108             registrableDomainsToRemove.append(entry.key);
2109     }
2110
2111     for (auto& registrableDomain : registrableDomainsToRemove)
2112         m_swappedProcessesPerRegistrableDomain.remove(registrableDomain);
2113 }
2114
2115 void WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, ProcessSwapRequestedByClient processSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
2116 {
2117     processForNavigationInternal(page, navigation, processSwapRequestedByClient, [this, page = makeRefPtr(page), navigation = makeRef(navigation), processSwapRequestedByClient, completionHandler = WTFMove(completionHandler)](Ref<WebProcessProxy>&& process, SuspendedPageProxy* suspendedPage, const String& reason) mutable {
2118         // We are process-swapping so automatic process prewarming would be beneficial if the client has not explicitly enabled / disabled it.
2119         bool doingAnAutomaticProcessSwap = processSwapRequestedByClient == ProcessSwapRequestedByClient::No && process.ptr() != &page->process();
2120         if (doingAnAutomaticProcessSwap && !configuration().wasAutomaticProcessWarmingSetByClient() && !configuration().clientWouldBenefitFromAutomaticProcessPrewarming()) {
2121             RELEASE_LOG(PerformanceLogging, "Automatically turning on process prewarming because the client would benefit from it");
2122             configuration().setClientWouldBenefitFromAutomaticProcessPrewarming(true);
2123         }
2124
2125         if (m_configuration->alwaysKeepAndReuseSwappedProcesses() && process.ptr() != &page->process()) {
2126             static std::once_flag onceFlag;
2127             std::call_once(onceFlag, [] {
2128                 WTFLogAlways("WARNING: The option to always keep swapped web processes alive is active. This is meant for debugging and testing only.");
2129             });
2130
2131             addProcessToOriginCacheSet(*page);
2132
2133             LOG(ProcessSwapping, "(ProcessSwapping) Navigating from %s to %s, keeping around old process. Now holding on to old processes for %u origins.", page->currentURL().utf8().data(), navigation->currentRequest().url().string().utf8().data(), m_swappedProcessesPerRegistrableDomain.size());
2134         }
2135
2136         completionHandler(WTFMove(process), suspendedPage, reason);
2137     });
2138 }
2139
2140 void WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, ProcessSwapRequestedByClient processSwapRequestedByClient, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
2141 {
2142     auto& targetURL = navigation.currentRequest().url();
2143
2144     auto createNewProcess = [&] () -> Ref<WebProcessProxy> {
2145         if (RefPtr<WebProcessProxy> process = tryTakePrewarmedProcess(page.websiteDataStore())) {
2146             tryPrewarmWithDomainInformation(*process, targetURL);
2147             return process.releaseNonNull();
2148         }
2149
2150         return createNewWebProcess(page.websiteDataStore());
2151     };
2152
2153     if (processSwapRequestedByClient == ProcessSwapRequestedByClient::Yes)
2154         return completionHandler(createNewProcess(), nullptr, "Process swap was requested by the client"_s);
2155
2156     if (!m_configuration->processSwapsOnNavigation())
2157         return completionHandler(page.process(), nullptr, "Feature is disabled"_s);
2158
2159     if (m_automationSession)
2160         return completionHandler(page.process(), nullptr, "An automation session is active"_s);
2161
2162     if (!page.process().hasCommittedAnyProvisionalLoads()) {
2163         tryPrewarmWithDomainInformation(page.process(), targetURL);
2164         return completionHandler(page.process(), nullptr, "Process has not yet committed any provisional loads"_s);
2165     }
2166
2167     // FIXME: We should support process swap when a window has been opened via window.open() without 'noopener'.
2168     // The issue is that the opener has a handle to the WindowProxy.
2169     if (navigation.openedByDOMWithOpener() && !m_configuration->processSwapsOnWindowOpenWithOpener())
2170         return completionHandler(page.process(), nullptr, "Browsing context been opened by DOM without 'noopener'"_s);
2171
2172     // FIXME: We should support process swap when a window has opened other windows via window.open.
2173     if (navigation.hasOpenedFrames())
2174         return completionHandler(page.process(), nullptr, "Browsing context has opened other windows"_s);
2175
2176     if (auto* backForwardListItem = navigation.targetItem()) {
2177         if (auto* suspendedPage = backForwardListItem->suspendedPage()) {
2178             return suspendedPage->waitUntilReadyToUnsuspend([createNewProcess = WTFMove(createNewProcess), completionHandler = WTFMove(completionHandler)](SuspendedPageProxy* suspendedPage) mutable {
2179                 if (!suspendedPage)
2180                     return completionHandler(createNewProcess(), nullptr, "Using new process because target back/forward item's suspended page is not reusable"_s);
2181                 Ref<WebProcessProxy> process = suspendedPage->process();
2182                 completionHandler(WTFMove(process), suspendedPage, "Using target back/forward item's process"_s);
2183             });
2184         }
2185
2186         // If the target back/forward item and the current back/forward item originated
2187         // in the same WebProcess then we should reuse the current WebProcess.
2188         if (auto* fromItem = navigation.fromItem()) {
2189             auto uiProcessIdentifier = Process::identifier();
2190             // In case of session restore, the item's process identifier is the UIProcess' identifier, in which case we do not want to do this check
2191             // or we'd never swap after a session restore.
2192             if (fromItem->itemID().processIdentifier == backForwardListItem->itemID().processIdentifier && backForwardListItem->itemID().processIdentifier != uiProcessIdentifier)
2193                 return completionHandler(page.process(), nullptr, "Source and target back/forward item originated in the same process"_s);
2194         }
2195     }
2196
2197     if (navigation.treatAsSameOriginNavigation())
2198         return completionHandler(page.process(), nullptr, "The treatAsSameOriginNavigation flag is set"_s);
2199
2200     URL sourceURL;
2201     if (page.isPageOpenedByDOMShowingInitialEmptyDocument() && !navigation.requesterOrigin().isEmpty())
2202         sourceURL = URL { URL(), navigation.requesterOrigin().toString() };
2203     else
2204         sourceURL = URL { { }, page.pageLoadState().url() };
2205
2206     if (sourceURL.isEmpty() && page.configuration().relatedPage()) {
2207         sourceURL = URL { { }, page.configuration().relatedPage()->pageLoadState().url() };
2208         RELEASE_LOG(ProcessSwapping, "Using related page %p's URL as source URL for process swap decision", page.configuration().relatedPage());
2209     }
2210
2211     if (!sourceURL.isValid() || !targetURL.isValid() || sourceURL.isEmpty() || sourceURL.protocolIsAbout() || registrableDomainsAreEqual(sourceURL, targetURL))
2212         return completionHandler(page.process(), nullptr, "Navigation is same-site"_s);
2213
2214     String reason = "Navigation is cross-site"_s;
2215     
2216     auto registrableDomain = toRegistrableDomain(targetURL);
2217     if (m_configuration->alwaysKeepAndReuseSwappedProcesses()) {
2218         LOG(ProcessSwapping, "(ProcessSwapping) Considering re-use of a previously cached process for domain %s", registrableDomain.utf8().data());
2219
2220         if (auto* process = m_swappedProcessesPerRegistrableDomain.get(registrableDomain)) {
2221             if (&process->websiteDataStore() == &page.websiteDataStore()) {
2222                 LOG(ProcessSwapping, "(ProcessSwapping) Reusing a previously cached process with pid %i to continue navigation to URL %s", process->processIdentifier(), targetURL.string().utf8().data());
2223
2224                 // FIXME: Architecturally we do not currently support multiple WebPage's with the same ID in a given WebProcess.
2225                 // In the case where this WebProcess has a SuspendedPageProxy for this WebPage, we can throw it away to support
2226                 // WebProcess re-use.
2227                 // In the future it would be great to refactor-out this limitation (https://bugs.webkit.org/show_bug.cgi?id=191166).
2228                 m_suspendedPages.removeAllMatching([&](auto& suspendedPage) {
2229                     return &suspendedPage->page() == &page && &suspendedPage->process() == process;
2230                 });
2231
2232                 return completionHandler(makeRef(*process), nullptr, reason);
2233             }
2234         }
2235     }
2236
2237     // Check if we have a suspended page for the given registrable domain and use its process if we do, for performance reasons.
2238     auto it = m_suspendedPages.findIf([&](auto& suspendedPage) {
2239         return suspendedPage->registrableDomain() == registrableDomain;
2240     });
2241     if (it != m_suspendedPages.end()) {
2242         Ref<WebProcessProxy> process = (*it)->process();
2243
2244         // FIXME: If the SuspendedPage is for this page, then we need to destroy the suspended page as we do not support having
2245         // multiple WebPages with the same ID in a given WebProcess currently (https://bugs.webkit.org/show_bug.cgi?id=191166).
2246         if (&(*it)->page() == &page)
2247             m_suspendedPages.remove(it);
2248
2249         if (&process->websiteDataStore() != &page.websiteDataStore())
2250             process->send(Messages::WebProcess::AddWebsiteDataStore(page.websiteDataStore().parameters()), 0);
2251
2252         return completionHandler(WTFMove(process), nullptr, reason);
2253     }
2254
2255     return completionHandler(createNewProcess(), nullptr, reason);
2256 }
2257
2258 void WebProcessPool::addSuspendedPage(std::unique_ptr<SuspendedPageProxy>&& suspendedPage)
2259 {
2260     if (m_suspendedPages.size() >= m_maxSuspendedPageCount)
2261         m_suspendedPages.removeFirst();
2262
2263     m_suspendedPages.append(WTFMove(suspendedPage));
2264 }
2265
2266 void WebProcessPool::removeAllSuspendedPagesForPage(WebPageProxy& page)
2267 {
2268     m_suspendedPages.removeAllMatching([&page](auto& suspendedPage) {
2269         return &suspendedPage->page() == &page;
2270     });
2271 }
2272
2273 std::unique_ptr<SuspendedPageProxy> WebProcessPool::takeSuspendedPage(SuspendedPageProxy& suspendedPage)
2274 {
2275     return m_suspendedPages.takeFirst([&suspendedPage](auto& item) {
2276         return item.get() == &suspendedPage;
2277     });
2278 }
2279
2280 void WebProcessPool::removeSuspendedPage(SuspendedPageProxy& suspendedPage)
2281 {
2282     auto it = m_suspendedPages.findIf([&suspendedPage](auto& item) {
2283         return item.get() == &suspendedPage;
2284     });
2285     if (it != m_suspendedPages.end())
2286         m_suspendedPages.remove(it);
2287 }
2288
2289 bool WebProcessPool::hasSuspendedPageFor(WebProcessProxy& process) const
2290 {
2291     return m_suspendedPages.findIf([&process](auto& suspendedPage) {
2292         return &suspendedPage->process() == &process;
2293     }) != m_suspendedPages.end();
2294 }
2295
2296 void WebProcessPool::addMockMediaDevice(const MockMediaDevice& device)
2297 {
2298 #if ENABLE(MEDIA_STREAM)
2299     MockRealtimeMediaSourceCenter::addDevice(device);
2300     sendToAllProcesses(Messages::WebProcess::AddMockMediaDevice { device });
2301 #endif
2302 }
2303
2304 void WebProcessPool::clearMockMediaDevices()
2305 {
2306 #if ENABLE(MEDIA_STREAM)
2307     MockRealtimeMediaSourceCenter::setDevices({ });
2308     sendToAllProcesses(Messages::WebProcess::ClearMockMediaDevices { });
2309 #endif
2310 }
2311
2312 void WebProcessPool::removeMockMediaDevice(const String& persistentId)
2313 {
2314 #if ENABLE(MEDIA_STREAM)
2315     MockRealtimeMediaSourceCenter::removeDevice(persistentId);
2316     sendToAllProcesses(Messages::WebProcess::RemoveMockMediaDevice { persistentId });
2317 #endif
2318 }
2319
2320 void WebProcessPool::resetMockMediaDevices()
2321 {
2322 #if ENABLE(MEDIA_STREAM)
2323     MockRealtimeMediaSourceCenter::resetDevices();
2324     sendToAllProcesses(Messages::WebProcess::ResetMockMediaDevices { });
2325 #endif
2326 }
2327
2328 void WebProcessPool::sendDisplayConfigurationChangedMessageForTesting()
2329 {
2330 #if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
2331     auto display = CGSMainDisplayID();
2332
2333     for (auto& processPool : WebProcessPool::allProcessPools()) {
2334         processPool->sendToAllProcesses(Messages::WebProcess::DisplayConfigurationChanged(display, kCGDisplayBeginConfigurationFlag));
2335         processPool->sendToAllProcesses(Messages::WebProcess::DisplayConfigurationChanged(display, kCGDisplaySetModeFlag | kCGDisplayDesktopShapeChangedFlag));
2336     }
2337 #endif
2338 }
2339
2340 void WebProcessPool::didCollectPrewarmInformation(const String& registrableDomain, const WebCore::PrewarmInformation& prewarmInformation)
2341 {
2342     static const size_t maximumSizeToPreventUnlimitedGrowth = 100;
2343     if (m_prewarmInformationPerRegistrableDomain.size() == maximumSizeToPreventUnlimitedGrowth)
2344         m_prewarmInformationPerRegistrableDomain.remove(m_prewarmInformationPerRegistrableDomain.random());
2345
2346     auto& value = m_prewarmInformationPerRegistrableDomain.ensure(registrableDomain, [] {
2347         return std::make_unique<WebCore::PrewarmInformation>();
2348     }).iterator->value;
2349
2350     *value = prewarmInformation;
2351 }
2352
2353 void WebProcessPool::tryPrewarmWithDomainInformation(WebProcessProxy& process, const URL& url)
2354 {
2355     auto* prewarmInformation = m_prewarmInformationPerRegistrableDomain.get(toRegistrableDomain(url));
2356     if (!prewarmInformation)
2357         return;
2358     process.send(Messages::WebProcess::PrewarmWithDomainInformation(*prewarmInformation), 0);
2359 }
2360
2361 void WebProcessPool::clearCurrentModifierStateForTesting()
2362 {
2363     sendToAllProcesses(Messages::WebProcess::ClearCurrentModifierStateForTesting());
2364 }
2365
2366 } // namespace WebKit