[WTF] Move currentCPUTime and sleep(Seconds) to CPUTime.h and Seconds.h respectively
[WebKit-https.git] / Source / WebKit / WebProcess / WebProcess.cpp
1 /*
2  * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebProcess.h"
28
29 #include "APIFrameHandle.h"
30 #include "APIPageGroupHandle.h"
31 #include "APIPageHandle.h"
32 #include "AuthenticationManager.h"
33 #include "ChildProcessMessages.h"
34 #include "DrawingArea.h"
35 #include "EventDispatcher.h"
36 #include "InjectedBundle.h"
37 #include "LibWebRTCNetwork.h"
38 #include "Logging.h"
39 #include "NetworkConnectionToWebProcessMessages.h"
40 #include "NetworkProcessConnection.h"
41 #include "NetworkSession.h"
42 #include "NetworkSessionCreationParameters.h"
43 #include "PluginProcessConnectionManager.h"
44 #include "SessionTracker.h"
45 #include "StatisticsData.h"
46 #include "StorageProcessMessages.h"
47 #include "UserData.h"
48 #include "WebAutomationSessionProxy.h"
49 #include "WebCacheStorageProvider.h"
50 #include "WebConnectionToUIProcess.h"
51 #include "WebCookieManager.h"
52 #include "WebCoreArgumentCoders.h"
53 #include "WebFrame.h"
54 #include "WebFrameNetworkingContext.h"
55 #include "WebGamepadProvider.h"
56 #include "WebGeolocationManager.h"
57 #include "WebLoaderStrategy.h"
58 #include "WebMediaKeyStorageManager.h"
59 #include "WebMemorySampler.h"
60 #include "WebMessagePortChannelProvider.h"
61 #include "WebPage.h"
62 #include "WebPageGroupProxy.h"
63 #include "WebPlatformStrategies.h"
64 #include "WebPluginInfoProvider.h"
65 #include "WebProcessCreationParameters.h"
66 #include "WebProcessMessages.h"
67 #include "WebProcessPoolMessages.h"
68 #include "WebProcessProxyMessages.h"
69 #include "WebResourceLoadStatisticsStoreMessages.h"
70 #include "WebSWContextManagerConnection.h"
71 #include "WebSWContextManagerConnectionMessages.h"
72 #include "WebServiceWorkerProvider.h"
73 #include "WebSocketStream.h"
74 #include "WebToStorageProcessConnection.h"
75 #include "WebsiteData.h"
76 #include "WebsiteDataStoreParameters.h"
77 #include "WebsiteDataType.h"
78 #include <JavaScriptCore/JSLock.h>
79 #include <JavaScriptCore/MemoryStatistics.h>
80 #include <JavaScriptCore/WasmFaultSignalHandler.h>
81 #include <WebCore/AXObjectCache.h>
82 #include <WebCore/ApplicationCacheStorage.h>
83 #include <WebCore/AuthenticationChallenge.h>
84 #include <WebCore/CPUMonitor.h>
85 #include <WebCore/CommonVM.h>
86 #include <WebCore/CrossOriginPreflightResultCache.h>
87 #include <WebCore/DNS.h>
88 #include <WebCore/DOMWindow.h>
89 #include <WebCore/DatabaseManager.h>
90 #include <WebCore/DatabaseTracker.h>
91 #include <WebCore/DeprecatedGlobalSettings.h>
92 #include <WebCore/DiagnosticLoggingClient.h>
93 #include <WebCore/DiagnosticLoggingKeys.h>
94 #include <WebCore/FontCache.h>
95 #include <WebCore/FontCascade.h>
96 #include <WebCore/Frame.h>
97 #include <WebCore/FrameLoader.h>
98 #include <WebCore/GCController.h>
99 #include <WebCore/GlyphPage.h>
100 #include <WebCore/HTMLMediaElement.h>
101 #include <WebCore/JSDOMWindow.h>
102 #include <WebCore/MainFrame.h>
103 #include <WebCore/MemoryCache.h>
104 #include <WebCore/MemoryRelease.h>
105 #include <WebCore/MessagePort.h>
106 #include <WebCore/NetworkStorageSession.h>
107 #include <WebCore/Page.h>
108 #include <WebCore/PageCache.h>
109 #include <WebCore/PageGroup.h>
110 #include <WebCore/PlatformMediaSessionManager.h>
111 #include <WebCore/ResourceLoadObserver.h>
112 #include <WebCore/ResourceLoadStatistics.h>
113 #include <WebCore/RuntimeApplicationChecks.h>
114 #include <WebCore/SchemeRegistry.h>
115 #include <WebCore/SecurityOrigin.h>
116 #include <WebCore/ServiceWorkerContextData.h>
117 #include <WebCore/Settings.h>
118 #include <WebCore/URLParser.h>
119 #include <WebCore/UserGestureIndicator.h>
120 #include <wtf/Language.h>
121 #include <wtf/RunLoop.h>
122 #include <wtf/text/StringHash.h>
123
124 #if !OS(WINDOWS)
125 #include <unistd.h>
126 #endif
127
128 #if PLATFORM(WAYLAND)
129 #include "WaylandCompositorDisplay.h"
130 #endif
131
132 #if PLATFORM(COCOA)
133 #include "ObjCObjectGraph.h"
134 #include "UserMediaCaptureManager.h"
135 #endif
136
137 #if ENABLE(SEC_ITEM_SHIM)
138 #include "SecItemShim.h"
139 #endif
140
141 #if ENABLE(NOTIFICATIONS)
142 #include "WebNotificationManager.h"
143 #endif
144
145 #if ENABLE(REMOTE_INSPECTOR)
146 #include <JavaScriptCore/RemoteInspector.h>
147 #endif
148
149 using namespace JSC;
150 using namespace WebCore;
151
152 // This should be less than plugInAutoStartExpirationTimeThreshold in PlugInAutoStartProvider.
153 static const Seconds plugInAutoStartExpirationTimeUpdateThreshold { 29 * 24 * 60 * 60 };
154
155 // This should be greater than tileRevalidationTimeout in TileController.
156 static const Seconds nonVisibleProcessCleanupDelay { 10_s };
157
158 namespace WebKit {
159
160 WebProcess& WebProcess::singleton()
161 {
162     static WebProcess& process = *new WebProcess;
163     return process;
164 }
165
166 WebProcess::WebProcess()
167     : m_eventDispatcher(EventDispatcher::create())
168 #if PLATFORM(IOS)
169     , m_viewUpdateDispatcher(ViewUpdateDispatcher::create())
170 #endif
171     , m_webInspectorInterruptDispatcher(WebInspectorInterruptDispatcher::create())
172     , m_webLoaderStrategy(*new WebLoaderStrategy)
173     , m_cacheStorageProvider(WebCacheStorageProvider::create())
174     , m_dnsPrefetchHystereris([this](PAL::HysteresisState state) { if (state == PAL::HysteresisState::Stopped) m_dnsPrefetchedHosts.clear(); })
175 #if ENABLE(NETSCAPE_PLUGIN_API)
176     , m_pluginProcessConnectionManager(PluginProcessConnectionManager::create())
177 #endif
178     , m_nonVisibleProcessCleanupTimer(*this, &WebProcess::nonVisibleProcessCleanupTimerFired)
179 #if PLATFORM(IOS)
180     , m_webSQLiteDatabaseTracker(*this)
181 #endif
182 {
183     // Initialize our platform strategies.
184     WebPlatformStrategies::initialize();
185
186     // FIXME: This should moved to where WebProcess::initialize is called,
187     // so that ports have a chance to customize, and ifdefs in this file are
188     // limited.
189     addSupplement<WebGeolocationManager>();
190     addSupplement<WebCookieManager>();
191
192 #if ENABLE(NOTIFICATIONS)
193     addSupplement<WebNotificationManager>();
194 #endif
195
196 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
197     addSupplement<WebMediaKeyStorageManager>();
198 #endif
199
200 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
201     addSupplement<UserMediaCaptureManager>();
202 #endif
203
204     m_plugInAutoStartOriginHashes.add(PAL::SessionID::defaultSessionID(), HashMap<unsigned, WallTime>());
205
206     ResourceLoadObserver::shared().setNotificationCallback([this] (Vector<ResourceLoadStatistics>&& statistics) {
207         ASSERT(!statistics.isEmpty());
208         parentProcessConnection()->send(Messages::WebResourceLoadStatisticsStore::ResourceLoadStatisticsUpdated(WTFMove(statistics)), 0);
209     });
210
211     Gigacage::disableDisablingPrimitiveGigacageIfShouldBeEnabled();
212 }
213
214 WebProcess::~WebProcess()
215 {
216 }
217
218 void WebProcess::initializeProcess(const ChildProcessInitializationParameters& parameters)
219 {
220     MessagePortChannelProvider::setSharedProvider(WebMessagePortChannelProvider::singleton());
221     
222 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
223     // This call is needed when the WebProcess is not running the NSApplication event loop.
224     // Otherwise, calling enableSandboxStyleFileQuarantine() will fail.
225     launchServicesCheckIn();
226 #endif
227     platformInitializeProcess(parameters);
228 }
229
230 void WebProcess::initializeConnection(IPC::Connection* connection)
231 {
232     ChildProcess::initializeConnection(connection);
233
234 #if !PLATFORM(GTK) && !PLATFORM(WPE)
235     connection->setShouldExitOnSyncMessageSendFailure(true);
236 #endif
237
238 #if HAVE(QOS_CLASSES)
239     connection->setShouldBoostMainThreadOnSyncMessage(true);
240 #endif
241
242     m_eventDispatcher->initializeConnection(connection);
243 #if PLATFORM(IOS)
244     m_viewUpdateDispatcher->initializeConnection(connection);
245 #endif // PLATFORM(IOS)
246     m_webInspectorInterruptDispatcher->initializeConnection(connection);
247
248 #if ENABLE(NETSCAPE_PLUGIN_API)
249     m_pluginProcessConnectionManager->initializeConnection(connection);
250 #endif
251
252     for (auto& supplement : m_supplements.values())
253         supplement->initializeConnection(connection);
254
255     m_webConnection = WebConnectionToUIProcess::create(this);
256
257     // In order to ensure that the asynchronous messages that are used for notifying the UI process
258     // about when WebFrame objects come and go are always delivered before the synchronous policy messages,
259     // use this flag to force synchronous messages to be treated as asynchronous messages in the UI process
260     // unless when doing so would lead to a deadlock.
261     connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true);
262 }
263
264 void WebProcess::initializeWebProcess(WebProcessCreationParameters&& parameters)
265 {    
266     ASSERT(m_pageMap.isEmpty());
267
268     WebCore::setPresentingApplicationPID(parameters.presentingApplicationPID);
269
270 #if OS(LINUX)
271     if (parameters.memoryPressureMonitorHandle.fileDescriptor() != -1)
272         MemoryPressureHandler::singleton().setMemoryPressureMonitorHandle(parameters.memoryPressureMonitorHandle.releaseFileDescriptor());
273     MemoryPressureHandler::ReliefLogger::setLoggingEnabled(parameters.shouldEnableMemoryPressureReliefLogging);
274 #endif
275
276     platformInitializeWebProcess(WTFMove(parameters));
277
278     // Match the QoS of the UIProcess and the scrolling thread but use a slightly lower priority.
279     WTF::Thread::setCurrentThreadIsUserInteractive(-1);
280
281     m_suppressMemoryPressureHandler = parameters.shouldSuppressMemoryPressureHandler;
282     if (!m_suppressMemoryPressureHandler) {
283         auto& memoryPressureHandler = MemoryPressureHandler::singleton();
284         memoryPressureHandler.setLowMemoryHandler([] (Critical critical, Synchronous synchronous) {
285             WebCore::releaseMemory(critical, synchronous);
286         });
287 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101200) || PLATFORM(GTK) || PLATFORM(WPE)
288         memoryPressureHandler.setShouldUsePeriodicMemoryMonitor(true);
289         memoryPressureHandler.setMemoryKillCallback([this] () {
290             WebCore::logMemoryStatisticsAtTimeOfDeath();
291             if (MemoryPressureHandler::singleton().processState() == WebsamProcessState::Active)
292                 parentProcessConnection()->send(Messages::WebProcessProxy::DidExceedActiveMemoryLimit(), 0);
293             else
294                 parentProcessConnection()->send(Messages::WebProcessProxy::DidExceedInactiveMemoryLimit(), 0);
295         });
296         memoryPressureHandler.setDidExceedInactiveLimitWhileActiveCallback([this] () {
297             parentProcessConnection()->send(Messages::WebProcessProxy::DidExceedInactiveMemoryLimitWhileActive(), 0);
298         });
299 #endif
300         memoryPressureHandler.setMemoryPressureStatusChangedCallback([this](bool isUnderMemoryPressure) {
301             if (parentProcessConnection())
302                 parentProcessConnection()->send(Messages::WebProcessProxy::MemoryPressureStatusChanged(isUnderMemoryPressure), 0);
303         });
304         memoryPressureHandler.install();
305     }
306
307     for (size_t i = 0, size = parameters.additionalSandboxExtensionHandles.size(); i < size; ++i)
308         SandboxExtension::consumePermanently(parameters.additionalSandboxExtensionHandles[i]);
309
310     if (!parameters.injectedBundlePath.isEmpty())
311         m_injectedBundle = InjectedBundle::create(parameters, transformHandlesToObjects(parameters.initializationUserData.object()).get());
312
313     for (auto& supplement : m_supplements.values())
314         supplement->initialize(parameters);
315
316     auto& databaseManager = DatabaseManager::singleton();
317     databaseManager.initialize(parameters.webSQLDatabaseDirectory);
318
319     // FIXME: This should be constructed per data store, not per process.
320     m_applicationCacheStorage = ApplicationCacheStorage::create(parameters.applicationCacheDirectory, parameters.applicationCacheFlatFileSubdirectoryName);
321 #if PLATFORM(IOS)
322     m_applicationCacheStorage->setDefaultOriginQuota(25ULL * 1024 * 1024);
323 #endif
324
325 #if ENABLE(VIDEO)
326     if (!parameters.mediaCacheDirectory.isEmpty())
327         WebCore::HTMLMediaElement::setMediaCacheDirectory(parameters.mediaCacheDirectory);
328 #endif
329
330     setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
331
332     if (!parameters.languages.isEmpty())
333         overrideUserPreferredLanguages(parameters.languages);
334
335     m_textCheckerState = parameters.textCheckerState;
336
337     m_fullKeyboardAccessEnabled = parameters.fullKeyboardAccessEnabled;
338
339     for (auto& scheme : parameters.urlSchemesRegisteredAsEmptyDocument)
340         registerURLSchemeAsEmptyDocument(scheme);
341
342     for (auto& scheme : parameters.urlSchemesRegisteredAsSecure)
343         registerURLSchemeAsSecure(scheme);
344
345     for (auto& scheme : parameters.urlSchemesRegisteredAsBypassingContentSecurityPolicy)
346         registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
347
348     for (auto& scheme : parameters.urlSchemesForWhichDomainRelaxationIsForbidden)
349         setDomainRelaxationForbiddenForURLScheme(scheme);
350
351     for (auto& scheme : parameters.urlSchemesRegisteredAsLocal)
352         registerURLSchemeAsLocal(scheme);
353
354     for (auto& scheme : parameters.urlSchemesRegisteredAsNoAccess)
355         registerURLSchemeAsNoAccess(scheme);
356
357     for (auto& scheme : parameters.urlSchemesRegisteredAsDisplayIsolated)
358         registerURLSchemeAsDisplayIsolated(scheme);
359
360     for (auto& scheme : parameters.urlSchemesRegisteredAsCORSEnabled)
361         registerURLSchemeAsCORSEnabled(scheme);
362
363     for (auto& scheme : parameters.urlSchemesRegisteredAsAlwaysRevalidated)
364         registerURLSchemeAsAlwaysRevalidated(scheme);
365
366     for (auto& scheme : parameters.urlSchemesRegisteredAsCachePartitioned)
367         registerURLSchemeAsCachePartitioned(scheme);
368
369     for (auto& scheme : parameters.urlSchemesServiceWorkersCanHandle)
370         registerURLSchemeServiceWorkersCanHandle(scheme);
371
372     setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval);
373
374     setResourceLoadStatisticsEnabled(parameters.resourceLoadStatisticsEnabled);
375
376     setAlwaysUsesComplexTextCodePath(parameters.shouldAlwaysUseComplexTextCodePath);
377
378     setShouldUseFontSmoothing(parameters.shouldUseFontSmoothing);
379
380     if (parameters.shouldUseTestingNetworkSession)
381         NetworkStorageSession::switchToNewTestingSession();
382
383     ensureNetworkProcessConnection();
384
385     setTerminationTimeout(parameters.terminationTimeout);
386
387     resetPlugInAutoStartOriginHashes(parameters.plugInAutoStartOriginHashes);
388     for (auto& origin : parameters.plugInAutoStartOrigins)
389         m_plugInAutoStartOrigins.add(origin);
390
391     setMemoryCacheDisabled(parameters.memoryCacheDisabled);
392
393 #if ENABLE(SERVICE_CONTROLS)
394     setEnabledServices(parameters.hasImageServices, parameters.hasSelectionServices, parameters.hasRichContentServices);
395 #endif
396
397 #if ENABLE(REMOTE_INSPECTOR) && PLATFORM(COCOA)
398     audit_token_t auditToken;
399     if (parentProcessConnection()->getAuditToken(auditToken)) {
400         RetainPtr<CFDataRef> auditData = adoptCF(CFDataCreate(nullptr, (const UInt8*)&auditToken, sizeof(auditToken)));
401         Inspector::RemoteInspector::singleton().setParentProcessInformation(WebCore::presentingApplicationPID(), auditData);
402     }
403 #endif
404
405 #if ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(MAC)
406     resetPluginLoadClientPolicies(parameters.pluginLoadClientPolicies);
407 #endif
408
409 #if ENABLE(GAMEPAD)
410     GamepadProvider::singleton().setSharedProvider(WebGamepadProvider::singleton());
411 #endif
412
413 #if ENABLE(SERVICE_WORKER)
414     ServiceWorkerProvider::setSharedProvider(WebServiceWorkerProvider::singleton());
415 #endif
416
417 #if ENABLE(WEBASSEMBLY)
418     JSC::Wasm::enableFastMemory();
419 #endif
420
421 #if HAVE(CFNETWORK_STORAGE_PARTITIONING) && !RELEASE_LOG_DISABLED
422     ResourceLoadObserver::shared().setShouldLogUserInteraction(parameters.shouldLogUserInteraction);
423 #endif
424
425     RELEASE_LOG(Process, "%p - WebProcess::initializeWebProcess: Presenting process = %d", this, WebCore::presentingApplicationPID());
426 }
427
428 void WebProcess::registerURLSchemeAsEmptyDocument(const String& urlScheme)
429 {
430     SchemeRegistry::registerURLSchemeAsEmptyDocument(urlScheme);
431 }
432
433 void WebProcess::registerURLSchemeAsSecure(const String& urlScheme) const
434 {
435     SchemeRegistry::registerURLSchemeAsSecure(urlScheme);
436 }
437
438 void WebProcess::registerURLSchemeAsBypassingContentSecurityPolicy(const String& urlScheme) const
439 {
440     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(urlScheme);
441 }
442
443 void WebProcess::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) const
444 {
445     SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(true, urlScheme);
446 }
447
448 void WebProcess::registerURLSchemeAsLocal(const String& urlScheme) const
449 {
450     SchemeRegistry::registerURLSchemeAsLocal(urlScheme);
451 }
452
453 void WebProcess::registerURLSchemeAsNoAccess(const String& urlScheme) const
454 {
455     SchemeRegistry::registerURLSchemeAsNoAccess(urlScheme);
456 }
457
458 void WebProcess::registerURLSchemeAsDisplayIsolated(const String& urlScheme) const
459 {
460     SchemeRegistry::registerURLSchemeAsDisplayIsolated(urlScheme);
461 }
462
463 void WebProcess::registerURLSchemeAsCORSEnabled(const String& urlScheme) const
464 {
465     SchemeRegistry::registerURLSchemeAsCORSEnabled(urlScheme);
466 }
467
468 void WebProcess::registerURLSchemeAsAlwaysRevalidated(const String& urlScheme) const
469 {
470     SchemeRegistry::registerURLSchemeAsAlwaysRevalidated(urlScheme);
471 }
472
473 void WebProcess::registerURLSchemeAsCachePartitioned(const String& urlScheme) const
474 {
475     SchemeRegistry::registerURLSchemeAsCachePartitioned(urlScheme);
476 }
477
478 void WebProcess::setDefaultRequestTimeoutInterval(double timeoutInterval)
479 {
480     ResourceRequest::setDefaultTimeoutInterval(timeoutInterval);
481 }
482
483 void WebProcess::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
484 {
485     WebCore::FontCascade::setCodePath(alwaysUseComplexText ? WebCore::FontCascade::Complex : WebCore::FontCascade::Auto);
486 }
487
488 void WebProcess::setShouldUseFontSmoothing(bool useFontSmoothing)
489 {
490     WebCore::FontCascade::setShouldUseSmoothing(useFontSmoothing);
491 }
492
493 void WebProcess::userPreferredLanguagesChanged(const Vector<String>& languages) const
494 {
495     overrideUserPreferredLanguages(languages);
496 }
497
498 void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
499 {
500     m_fullKeyboardAccessEnabled = fullKeyboardAccessEnabled;
501 }
502
503 void WebProcess::addWebsiteDataStore(WebsiteDataStoreParameters&& parameters)
504 {
505     WebFrameNetworkingContext::ensureWebsiteDataStoreSession(WTFMove(parameters));
506 }
507
508 void WebProcess::destroySession(PAL::SessionID sessionID)
509 {
510     SessionTracker::destroySession(sessionID);
511 }
512
513 void WebProcess::ensureLegacyPrivateBrowsingSessionInNetworkProcess()
514 {
515     ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::EnsureLegacyPrivateBrowsingSession(), 0);
516 }
517
518 #if ENABLE(NETSCAPE_PLUGIN_API)
519 PluginProcessConnectionManager& WebProcess::pluginProcessConnectionManager()
520 {
521     return *m_pluginProcessConnectionManager;
522 }
523 #endif
524
525 void WebProcess::setCacheModel(uint32_t cm)
526 {
527     CacheModel cacheModel = static_cast<CacheModel>(cm);
528
529     if (m_hasSetCacheModel && (cacheModel == m_cacheModel))
530         return;
531
532     m_hasSetCacheModel = true;
533     m_cacheModel = cacheModel;
534
535     unsigned cacheTotalCapacity = 0;
536     unsigned cacheMinDeadCapacity = 0;
537     unsigned cacheMaxDeadCapacity = 0;
538     Seconds deadDecodedDataDeletionInterval;
539     unsigned pageCacheSize = 0;
540     calculateMemoryCacheSizes(cacheModel, cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval, pageCacheSize);
541
542     auto& memoryCache = MemoryCache::singleton();
543     memoryCache.setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity);
544     memoryCache.setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval);
545     PageCache::singleton().setMaxSize(pageCacheSize);
546
547     platformSetCacheModel(cacheModel);
548 }
549
550 void WebProcess::clearCachedCredentials()
551 {
552     NetworkStorageSession::defaultStorageSession().credentialStorage().clearCredentials();
553 }
554
555 WebPage* WebProcess::focusedWebPage() const
556 {    
557     for (auto& page : m_pageMap.values()) {
558         if (page->windowAndWebPageAreFocused())
559             return page.get();
560     }
561     return 0;
562 }
563     
564 WebPage* WebProcess::webPage(uint64_t pageID) const
565 {
566     return m_pageMap.get(pageID);
567 }
568
569 void WebProcess::createWebPage(uint64_t pageID, WebPageCreationParameters&& parameters)
570 {
571     // It is necessary to check for page existence here since during a window.open() (or targeted
572     // link) the WebPage gets created both in the synchronous handler and through the normal way. 
573     HashMap<uint64_t, RefPtr<WebPage>>::AddResult result = m_pageMap.add(pageID, nullptr);
574     if (result.isNewEntry) {
575         ASSERT(!result.iterator->value);
576         result.iterator->value = WebPage::create(pageID, WTFMove(parameters));
577
578         // Balanced by an enableTermination in removeWebPage.
579         disableTermination();
580         updateCPULimit();
581     } else
582         result.iterator->value->reinitializeWebPage(WTFMove(parameters));
583
584     ASSERT(result.iterator->value);
585 }
586
587 void WebProcess::removeWebPage(uint64_t pageID)
588 {
589     ASSERT(m_pageMap.contains(pageID));
590
591     pageWillLeaveWindow(pageID);
592     m_pageMap.remove(pageID);
593
594     enableTermination();
595     updateCPULimit();
596 }
597
598 bool WebProcess::shouldTerminate()
599 {
600     ASSERT(m_pageMap.isEmpty());
601
602     // FIXME: the ShouldTerminate message should also send termination parameters, such as any session cookies that need to be preserved.
603     bool shouldTerminate = false;
604     if (parentProcessConnection()->sendSync(Messages::WebProcessProxy::ShouldTerminate(), Messages::WebProcessProxy::ShouldTerminate::Reply(shouldTerminate), 0)
605         && !shouldTerminate)
606         return false;
607
608     return true;
609 }
610
611 void WebProcess::terminate()
612 {
613 #ifndef NDEBUG
614     GCController::singleton().garbageCollectNow();
615     FontCache::singleton().invalidate();
616     MemoryCache::singleton().setDisabled(true);
617 #endif
618
619     m_webConnection->invalidate();
620     m_webConnection = nullptr;
621
622     platformTerminate();
623
624     ChildProcess::terminate();
625 }
626
627 void WebProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::Decoder& decoder, std::unique_ptr<IPC::Encoder>& replyEncoder)
628 {
629     if (messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder))
630         return;
631
632     didReceiveSyncWebProcessMessage(connection, decoder, replyEncoder);
633 }
634
635 void WebProcess::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
636 {
637     if (messageReceiverMap().dispatchMessage(connection, decoder))
638         return;
639
640     if (decoder.messageReceiverName() == Messages::WebProcess::messageReceiverName()) {
641         didReceiveWebProcessMessage(connection, decoder);
642         return;
643     }
644
645     if (decoder.messageReceiverName() == Messages::ChildProcess::messageReceiverName()) {
646         ChildProcess::didReceiveMessage(connection, decoder);
647         return;
648     }
649
650 #if ENABLE(SERVICE_WORKER)
651     // FIXME: Remove?
652     if (decoder.messageReceiverName() == Messages::WebSWContextManagerConnection::messageReceiverName()) {
653         ASSERT(SWContextManager::singleton().connection());
654         if (auto* contextManagerConnection = SWContextManager::singleton().connection())
655             static_cast<WebSWContextManagerConnection&>(*contextManagerConnection).didReceiveMessage(connection, decoder);
656         return;
657     }
658 #endif
659
660     LOG_ERROR("Unhandled web process message '%s:%s'", decoder.messageReceiverName().toString().data(), decoder.messageName().toString().data());
661 }
662
663 void WebProcess::didClose(IPC::Connection&)
664 {
665 #ifndef NDEBUG
666     for (auto& page : copyToVector(m_pageMap.values()))
667         page->close();
668
669     GCController::singleton().garbageCollectSoon();
670     FontCache::singleton().invalidate();
671     MemoryCache::singleton().setDisabled(true);
672 #endif
673
674 #if ENABLE(VIDEO)
675     // FIXME(146657): This explicit media stop command should not be necessary
676     if (auto* platformMediaSessionManager = PlatformMediaSessionManager::sharedManagerIfExists())
677         platformMediaSessionManager->stopAllMediaPlaybackForProcess();
678 #endif
679
680     // The UI process closed this connection, shut down.
681     stopRunLoop();
682 }
683
684 WebFrame* WebProcess::webFrame(uint64_t frameID) const
685 {
686     return m_frameMap.get(frameID);
687 }
688
689 void WebProcess::addWebFrame(uint64_t frameID, WebFrame* frame)
690 {
691     m_frameMap.set(frameID, frame);
692 }
693
694 void WebProcess::removeWebFrame(uint64_t frameID)
695 {
696     m_frameMap.remove(frameID);
697
698     // We can end up here after our connection has closed when WebCore's frame life-support timer
699     // fires when the application is shutting down. There's no need (and no way) to update the UI
700     // process in this case.
701     if (!parentProcessConnection())
702         return;
703
704     parentProcessConnection()->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0);
705 }
706
707 WebPageGroupProxy* WebProcess::webPageGroup(PageGroup* pageGroup)
708 {
709     for (auto& page : m_pageGroupMap.values()) {
710         if (page->corePageGroup() == pageGroup)
711             return page.get();
712     }
713
714     return 0;
715 }
716
717 WebPageGroupProxy* WebProcess::webPageGroup(uint64_t pageGroupID)
718 {
719     return m_pageGroupMap.get(pageGroupID);
720 }
721
722 WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupData)
723 {
724     auto result = m_pageGroupMap.add(pageGroupData.pageGroupID, nullptr);
725     if (result.isNewEntry) {
726         ASSERT(!result.iterator->value);
727         result.iterator->value = WebPageGroupProxy::create(pageGroupData);
728     }
729
730     return result.iterator->value.get();
731 }
732
733 static uint64_t nextUserGestureTokenIdentifier()
734 {
735     static uint64_t identifier = 1;
736     return identifier++;
737 }
738
739 uint64_t WebProcess::userGestureTokenIdentifier(RefPtr<UserGestureToken> token)
740 {
741     if (!token || !token->processingUserGesture())
742         return 0;
743
744     auto result = m_userGestureTokens.ensure(token.get(), [] { return nextUserGestureTokenIdentifier(); });
745     if (result.isNewEntry) {
746         result.iterator->key->addDestructionObserver([] (UserGestureToken& tokenBeingDestroyed) {
747             WebProcess::singleton().userGestureTokenDestroyed(tokenBeingDestroyed);
748         });
749     }
750     
751     return result.iterator->value;
752 }
753
754 void WebProcess::userGestureTokenDestroyed(UserGestureToken& token)
755 {
756     auto identifier = m_userGestureTokens.take(&token);
757     parentProcessConnection()->send(Messages::WebProcessProxy::DidDestroyUserGestureToken(identifier), 0);
758 }
759
760 void WebProcess::clearResourceCaches(ResourceCachesToClear resourceCachesToClear)
761 {
762     // Toggling the cache model like this forces the cache to evict all its in-memory resources.
763     // FIXME: We need a better way to do this.
764     CacheModel cacheModel = m_cacheModel;
765     setCacheModel(CacheModelDocumentViewer);
766     setCacheModel(cacheModel);
767
768     MemoryCache::singleton().evictResources();
769
770     // Empty the cross-origin preflight cache.
771     CrossOriginPreflightResultCache::singleton().empty();
772 }
773
774 static inline void addCaseFoldedCharacters(StringHasher& hasher, const String& string)
775 {
776     if (string.isEmpty())
777         return;
778     if (string.is8Bit()) {
779         hasher.addCharacters<LChar, ASCIICaseInsensitiveHash::FoldCase<LChar>>(string.characters8(), string.length());
780         return;
781     }
782     hasher.addCharacters<UChar, ASCIICaseInsensitiveHash::FoldCase<UChar>>(string.characters16(), string.length());
783 }
784
785 static unsigned hashForPlugInOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType)
786 {
787     // We want to avoid concatenating the strings and then taking the hash, since that could lead to an expensive conversion.
788     // We also want to avoid using the hash() function in StringImpl or ASCIICaseInsensitiveHash because that masks out bits for the use of flags.
789     StringHasher hasher;
790     addCaseFoldedCharacters(hasher, pageOrigin);
791     hasher.addCharacter(0);
792     addCaseFoldedCharacters(hasher, pluginOrigin);
793     hasher.addCharacter(0);
794     addCaseFoldedCharacters(hasher, mimeType);
795     return hasher.hash();
796 }
797
798 bool WebProcess::isPlugInAutoStartOriginHash(unsigned plugInOriginHash, PAL::SessionID sessionID)
799 {
800     HashMap<PAL::SessionID, HashMap<unsigned, WallTime>>::const_iterator sessionIterator = m_plugInAutoStartOriginHashes.find(sessionID);
801     HashMap<unsigned, WallTime>::const_iterator it;
802     bool contains = false;
803
804     if (sessionIterator != m_plugInAutoStartOriginHashes.end()) {
805         it = sessionIterator->value.find(plugInOriginHash);
806         contains = it != sessionIterator->value.end();
807     }
808     if (!contains) {
809         sessionIterator = m_plugInAutoStartOriginHashes.find(PAL::SessionID::defaultSessionID());
810         it = sessionIterator->value.find(plugInOriginHash);
811         if (it == sessionIterator->value.end())
812             return false;
813     }
814     return WallTime::now() < it->value;
815 }
816
817 bool WebProcess::shouldPlugInAutoStartFromOrigin(WebPage& webPage, const String& pageOrigin, const String& pluginOrigin, const String& mimeType)
818 {
819     if (!pluginOrigin.isEmpty() && m_plugInAutoStartOrigins.contains(pluginOrigin))
820         return true;
821
822 #ifdef ENABLE_PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC
823     // The plugin wasn't in the general whitelist, so check if it similar to the primary plugin for the page (if we've found one).
824     if (webPage.matchesPrimaryPlugIn(pageOrigin, pluginOrigin, mimeType))
825         return true;
826 #else
827     UNUSED_PARAM(webPage);
828 #endif
829
830     // Lastly check against the more explicit hash list.
831     return isPlugInAutoStartOriginHash(hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType), webPage.sessionID());
832 }
833
834 void WebProcess::plugInDidStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType, PAL::SessionID sessionID)
835 {
836     if (pageOrigin.isEmpty()) {
837         LOG(Plugins, "Not adding empty page origin");
838         return;
839     }
840
841     unsigned plugInOriginHash = hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType);
842     if (isPlugInAutoStartOriginHash(plugInOriginHash, sessionID)) {
843         LOG(Plugins, "Hash %x already exists as auto-start origin (request for %s)", plugInOriginHash, pageOrigin.utf8().data());
844         return;
845     }
846
847     // We might attempt to start another plugin before the didAddPlugInAutoStartOrigin message
848     // comes back from the parent process. Temporarily add this hash to the list with a thirty
849     // second timeout. That way, even if the parent decides not to add it, we'll only be
850     // incorrect for a little while.
851     m_plugInAutoStartOriginHashes.add(sessionID, HashMap<unsigned, WallTime>()).iterator->value.set(plugInOriginHash, WallTime::now() + 30_s * 1000);
852
853     parentProcessConnection()->send(Messages::WebProcessPool::AddPlugInAutoStartOriginHash(pageOrigin, plugInOriginHash, sessionID), 0);
854 }
855
856 void WebProcess::didAddPlugInAutoStartOriginHash(unsigned plugInOriginHash, WallTime expirationTime, PAL::SessionID sessionID)
857 {
858     // When called, some web process (which also might be this one) added the origin for auto-starting,
859     // or received user interaction.
860     // Set the bit to avoid having redundantly call into the UI process upon user interaction.
861     m_plugInAutoStartOriginHashes.add(sessionID, HashMap<unsigned, WallTime>()).iterator->value.set(plugInOriginHash, expirationTime);
862 }
863
864 void WebProcess::resetPlugInAutoStartOriginDefaultHashes(const HashMap<unsigned, WallTime>& hashes)
865 {
866     m_plugInAutoStartOriginHashes.clear();
867     m_plugInAutoStartOriginHashes.add(PAL::SessionID::defaultSessionID(), HashMap<unsigned, WallTime>()).iterator->value.swap(const_cast<HashMap<unsigned, WallTime>&>(hashes));
868 }
869
870 void WebProcess::resetPlugInAutoStartOriginHashes(const HashMap<PAL::SessionID, HashMap<unsigned, WallTime>>& hashes)
871 {
872     m_plugInAutoStartOriginHashes.swap(const_cast<HashMap<PAL::SessionID, HashMap<unsigned, WallTime>>&>(hashes));
873 }
874
875 void WebProcess::plugInDidReceiveUserInteraction(const String& pageOrigin, const String& pluginOrigin, const String& mimeType, PAL::SessionID sessionID)
876 {
877     if (pageOrigin.isEmpty())
878         return;
879
880     unsigned plugInOriginHash = hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType);
881     if (!plugInOriginHash)
882         return;
883
884     HashMap<PAL::SessionID, HashMap<unsigned, WallTime>>::const_iterator sessionIterator = m_plugInAutoStartOriginHashes.find(sessionID);
885     HashMap<unsigned, WallTime>::const_iterator it;
886     bool contains = false;
887     if (sessionIterator != m_plugInAutoStartOriginHashes.end()) {
888         it = sessionIterator->value.find(plugInOriginHash);
889         contains = it != sessionIterator->value.end();
890     }
891     if (!contains) {
892         sessionIterator = m_plugInAutoStartOriginHashes.find(PAL::SessionID::defaultSessionID());
893         it = sessionIterator->value.find(plugInOriginHash);
894         if (it == sessionIterator->value.end())
895             return;
896     }
897
898     if (it->value - WallTime::now() > plugInAutoStartExpirationTimeUpdateThreshold)
899         return;
900
901     parentProcessConnection()->send(Messages::WebProcessPool::PlugInDidReceiveUserInteraction(plugInOriginHash, sessionID), 0);
902 }
903
904 void WebProcess::setPluginLoadClientPolicy(uint8_t policy, const String& host, const String& bundleIdentifier, const String& versionString)
905 {
906 #if ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(MAC)
907     WebPluginInfoProvider::singleton().setPluginLoadClientPolicy(static_cast<PluginLoadClientPolicy>(policy), host, bundleIdentifier, versionString);
908 #endif
909 }
910
911 void WebProcess::resetPluginLoadClientPolicies(const HashMap<WTF::String, HashMap<WTF::String, HashMap<WTF::String, uint8_t>>>& pluginLoadClientPolicies)
912 {
913 #if ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(MAC)
914     clearPluginClientPolicies();
915
916     for (auto& hostPair : pluginLoadClientPolicies) {
917         for (auto& bundleIdentifierPair : hostPair.value) {
918             for (auto& versionPair : bundleIdentifierPair.value)
919                 WebPluginInfoProvider::singleton().setPluginLoadClientPolicy(static_cast<PluginLoadClientPolicy>(versionPair.value), hostPair.key, bundleIdentifierPair.key, versionPair.key);
920         }
921     }
922 #endif
923 }
924
925 void WebProcess::clearPluginClientPolicies()
926 {
927 #if ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(MAC)
928     WebPluginInfoProvider::singleton().clearPluginClientPolicies();
929 #endif
930 }
931
932 void WebProcess::refreshPlugins()
933 {
934 #if ENABLE(NETSCAPE_PLUGIN_API)
935     WebPluginInfoProvider::singleton().refresh(false);
936 #endif
937 }
938
939 static void fromCountedSetToHashMap(TypeCountSet* countedSet, HashMap<String, uint64_t>& map)
940 {
941     TypeCountSet::const_iterator end = countedSet->end();
942     for (TypeCountSet::const_iterator it = countedSet->begin(); it != end; ++it)
943         map.set(it->key, it->value);
944 }
945
946 static void getWebCoreMemoryCacheStatistics(Vector<HashMap<String, uint64_t>>& result)
947 {
948     String imagesString(ASCIILiteral("Images"));
949     String cssString(ASCIILiteral("CSS"));
950     String xslString(ASCIILiteral("XSL"));
951     String javaScriptString(ASCIILiteral("JavaScript"));
952     
953     MemoryCache::Statistics memoryCacheStatistics = MemoryCache::singleton().getStatistics();
954     
955     HashMap<String, uint64_t> counts;
956     counts.set(imagesString, memoryCacheStatistics.images.count);
957     counts.set(cssString, memoryCacheStatistics.cssStyleSheets.count);
958     counts.set(xslString, memoryCacheStatistics.xslStyleSheets.count);
959     counts.set(javaScriptString, memoryCacheStatistics.scripts.count);
960     result.append(counts);
961     
962     HashMap<String, uint64_t> sizes;
963     sizes.set(imagesString, memoryCacheStatistics.images.size);
964     sizes.set(cssString, memoryCacheStatistics.cssStyleSheets.size);
965     sizes.set(xslString, memoryCacheStatistics.xslStyleSheets.size);
966     sizes.set(javaScriptString, memoryCacheStatistics.scripts.size);
967     result.append(sizes);
968     
969     HashMap<String, uint64_t> liveSizes;
970     liveSizes.set(imagesString, memoryCacheStatistics.images.liveSize);
971     liveSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.liveSize);
972     liveSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.liveSize);
973     liveSizes.set(javaScriptString, memoryCacheStatistics.scripts.liveSize);
974     result.append(liveSizes);
975     
976     HashMap<String, uint64_t> decodedSizes;
977     decodedSizes.set(imagesString, memoryCacheStatistics.images.decodedSize);
978     decodedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.decodedSize);
979     decodedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.decodedSize);
980     decodedSizes.set(javaScriptString, memoryCacheStatistics.scripts.decodedSize);
981     result.append(decodedSizes);
982 }
983
984 void WebProcess::getWebCoreStatistics(uint64_t callbackID)
985 {
986     StatisticsData data;
987     
988     // Gather JavaScript statistics.
989     {
990         JSLockHolder lock(commonVM());
991         data.statisticsNumbers.set(ASCIILiteral("JavaScriptObjectsCount"), commonVM().heap.objectCount());
992         data.statisticsNumbers.set(ASCIILiteral("JavaScriptGlobalObjectsCount"), commonVM().heap.globalObjectCount());
993         data.statisticsNumbers.set(ASCIILiteral("JavaScriptProtectedObjectsCount"), commonVM().heap.protectedObjectCount());
994         data.statisticsNumbers.set(ASCIILiteral("JavaScriptProtectedGlobalObjectsCount"), commonVM().heap.protectedGlobalObjectCount());
995         
996         std::unique_ptr<TypeCountSet> protectedObjectTypeCounts(commonVM().heap.protectedObjectTypeCounts());
997         fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts);
998         
999         std::unique_ptr<TypeCountSet> objectTypeCounts(commonVM().heap.objectTypeCounts());
1000         fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts);
1001         
1002         uint64_t javaScriptHeapSize = commonVM().heap.size();
1003         data.statisticsNumbers.set(ASCIILiteral("JavaScriptHeapSize"), javaScriptHeapSize);
1004         data.statisticsNumbers.set(ASCIILiteral("JavaScriptFreeSize"), commonVM().heap.capacity() - javaScriptHeapSize);
1005     }
1006
1007     WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics();
1008     data.statisticsNumbers.set(ASCIILiteral("FastMallocReservedVMBytes"), fastMallocStatistics.reservedVMBytes);
1009     data.statisticsNumbers.set(ASCIILiteral("FastMallocCommittedVMBytes"), fastMallocStatistics.committedVMBytes);
1010     data.statisticsNumbers.set(ASCIILiteral("FastMallocFreeListBytes"), fastMallocStatistics.freeListBytes);
1011     
1012     // Gather font statistics.
1013     auto& fontCache = FontCache::singleton();
1014     data.statisticsNumbers.set(ASCIILiteral("CachedFontDataCount"), fontCache.fontCount());
1015     data.statisticsNumbers.set(ASCIILiteral("CachedFontDataInactiveCount"), fontCache.inactiveFontCount());
1016     
1017     // Gather glyph page statistics.
1018     data.statisticsNumbers.set(ASCIILiteral("GlyphPageCount"), GlyphPage::count());
1019     
1020     // Get WebCore memory cache statistics
1021     getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics);
1022     
1023     parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0);
1024 }
1025
1026 void WebProcess::garbageCollectJavaScriptObjects()
1027 {
1028     GCController::singleton().garbageCollectNow();
1029 }
1030
1031 void WebProcess::mainThreadPing()
1032 {
1033     parentProcessConnection()->send(Messages::WebProcessProxy::DidReceiveMainThreadPing(), 0);
1034 }
1035
1036 void WebProcess::backgroundResponsivenessPing()
1037 {
1038     parentProcessConnection()->send(Messages::WebProcessProxy::DidReceiveBackgroundResponsivenessPing(), 0);
1039 }
1040
1041 void WebProcess::syncIPCMessageWhileWaitingForSyncReplyForTesting()
1042 {
1043 }
1044
1045 void WebProcess::didTakeAllMessagesForPort(Vector<MessageWithMessagePorts>&& messages, uint64_t messageCallbackIdentifier, uint64_t messageBatchIdentifier)
1046 {
1047     WebMessagePortChannelProvider::singleton().didTakeAllMessagesForPort(WTFMove(messages), messageCallbackIdentifier, messageBatchIdentifier);
1048 }
1049
1050 void WebProcess::checkProcessLocalPortForActivity(const MessagePortIdentifier& port, uint64_t callbackIdentifier)
1051 {
1052     WebMessagePortChannelProvider::singleton().checkProcessLocalPortForActivity(port, callbackIdentifier);
1053 }
1054
1055 void WebProcess::didCheckRemotePortForActivity(uint64_t callbackIdentifier, bool hasActivity)
1056 {
1057     WebMessagePortChannelProvider::singleton().didCheckRemotePortForActivity(callbackIdentifier, hasActivity);
1058 }
1059
1060 void WebProcess::messagesAvailableForPort(const MessagePortIdentifier& identifier)
1061 {
1062     MessagePort::notifyMessageAvailable(identifier);
1063 }
1064
1065 #if ENABLE(GAMEPAD)
1066
1067 void WebProcess::setInitialGamepads(const Vector<WebKit::GamepadData>& gamepadDatas)
1068 {
1069     WebGamepadProvider::singleton().setInitialGamepads(gamepadDatas);
1070 }
1071
1072 void WebProcess::gamepadConnected(const GamepadData& gamepadData)
1073 {
1074     WebGamepadProvider::singleton().gamepadConnected(gamepadData);
1075 }
1076
1077 void WebProcess::gamepadDisconnected(unsigned index)
1078 {
1079     WebGamepadProvider::singleton().gamepadDisconnected(index);
1080 }
1081
1082 #endif
1083
1084 void WebProcess::setJavaScriptGarbageCollectorTimerEnabled(bool flag)
1085 {
1086     GCController::singleton().setJavaScriptGarbageCollectorTimerEnabled(flag);
1087 }
1088
1089 void WebProcess::handleInjectedBundleMessage(const String& messageName, const UserData& messageBody)
1090 {
1091     InjectedBundle* injectedBundle = WebProcess::singleton().injectedBundle();
1092     if (!injectedBundle)
1093         return;
1094
1095     injectedBundle->didReceiveMessage(messageName, transformHandlesToObjects(messageBody.object()).get());
1096 }
1097
1098 void WebProcess::setInjectedBundleParameter(const String& key, const IPC::DataReference& value)
1099 {
1100     InjectedBundle* injectedBundle = WebProcess::singleton().injectedBundle();
1101     if (!injectedBundle)
1102         return;
1103
1104     injectedBundle->setBundleParameter(key, value);
1105 }
1106
1107 void WebProcess::setInjectedBundleParameters(const IPC::DataReference& value)
1108 {
1109     InjectedBundle* injectedBundle = WebProcess::singleton().injectedBundle();
1110     if (!injectedBundle)
1111         return;
1112
1113     injectedBundle->setBundleParameters(value);
1114 }
1115
1116 NetworkProcessConnection& WebProcess::ensureNetworkProcessConnection()
1117 {
1118     // If we've lost our connection to the network process (e.g. it crashed) try to re-establish it.
1119     if (!m_networkProcessConnection) {
1120         IPC::Attachment encodedConnectionIdentifier;
1121
1122         if (!parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetNetworkProcessConnection(), Messages::WebProcessProxy::GetNetworkProcessConnection::Reply(encodedConnectionIdentifier), 0, Seconds::infinity(), IPC::SendSyncOption::DoNotProcessIncomingMessagesWhenWaitingForSyncReply))
1123             CRASH();
1124
1125 #if USE(UNIX_DOMAIN_SOCKETS)
1126         IPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.releaseFileDescriptor();
1127 #elif OS(DARWIN)
1128         IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port());
1129 #elif OS(WINDOWS)
1130         IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.handle());
1131 #else
1132         ASSERT_NOT_REACHED();
1133 #endif
1134         if (IPC::Connection::identifierIsNull(connectionIdentifier))
1135             CRASH();
1136         m_networkProcessConnection = NetworkProcessConnection::create(connectionIdentifier);
1137     }
1138     
1139     return *m_networkProcessConnection;
1140 }
1141
1142 void WebProcess::logDiagnosticMessageForNetworkProcessCrash()
1143 {
1144     WebCore::Page* page = nullptr;
1145
1146     if (auto* webPage = focusedWebPage())
1147         page = webPage->corePage();
1148
1149     if (!page) {
1150         for (auto& webPage : m_pageMap.values()) {
1151             if (auto* corePage = webPage->corePage()) {
1152                 page = corePage;
1153                 break;
1154             }
1155         }
1156     }
1157
1158     if (page)
1159         page->diagnosticLoggingClient().logDiagnosticMessage(WebCore::DiagnosticLoggingKeys::internalErrorKey(), WebCore::DiagnosticLoggingKeys::networkProcessCrashedKey(), WebCore::ShouldSample::No);
1160 }
1161
1162 void WebProcess::networkProcessConnectionClosed(NetworkProcessConnection* connection)
1163 {
1164     ASSERT(m_networkProcessConnection);
1165     ASSERT_UNUSED(connection, m_networkProcessConnection == connection);
1166
1167     m_networkProcessConnection = nullptr;
1168
1169     logDiagnosticMessageForNetworkProcessCrash();
1170
1171     m_webLoaderStrategy.networkProcessCrashed();
1172     WebSocketStream::networkProcessCrashed();
1173
1174     for (auto& page : m_pageMap.values())
1175         page->stopAllURLSchemeTasks();
1176 }
1177
1178 WebLoaderStrategy& WebProcess::webLoaderStrategy()
1179 {
1180     return m_webLoaderStrategy;
1181 }
1182
1183 void WebProcess::webToStorageProcessConnectionClosed(WebToStorageProcessConnection* connection)
1184 {
1185     ASSERT(m_webToStorageProcessConnection);
1186     ASSERT(m_webToStorageProcessConnection == connection);
1187
1188     m_webToStorageProcessConnection = nullptr;
1189 }
1190
1191 WebToStorageProcessConnection& WebProcess::ensureWebToStorageProcessConnection(PAL::SessionID initialSessionID)
1192 {
1193     if (!m_webToStorageProcessConnection) {
1194         IPC::Attachment encodedConnectionIdentifier;
1195
1196         if (!parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetStorageProcessConnection(initialSessionID), Messages::WebProcessProxy::GetStorageProcessConnection::Reply(encodedConnectionIdentifier), 0))
1197             CRASH();
1198
1199 #if USE(UNIX_DOMAIN_SOCKETS)
1200         IPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.releaseFileDescriptor();
1201 #elif OS(DARWIN)
1202         IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port());
1203 #elif OS(WINDOWS)
1204         IPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.handle());
1205 #else
1206         ASSERT_NOT_REACHED();
1207 #endif
1208         if (IPC::Connection::identifierIsNull(connectionIdentifier))
1209             CRASH();
1210         m_webToStorageProcessConnection = WebToStorageProcessConnection::create(connectionIdentifier);
1211
1212     }
1213     return *m_webToStorageProcessConnection;
1214 }
1215
1216 void WebProcess::setEnhancedAccessibility(bool flag)
1217 {
1218     WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility(flag);
1219 }
1220     
1221 void WebProcess::startMemorySampler(SandboxExtension::Handle&& sampleLogFileHandle, const String& sampleLogFilePath, const double interval)
1222 {
1223 #if ENABLE(MEMORY_SAMPLER)    
1224     WebMemorySampler::singleton()->start(WTFMove(sampleLogFileHandle), sampleLogFilePath, interval);
1225 #else
1226     UNUSED_PARAM(sampleLogFileHandle);
1227     UNUSED_PARAM(sampleLogFilePath);
1228     UNUSED_PARAM(interval);
1229 #endif
1230 }
1231     
1232 void WebProcess::stopMemorySampler()
1233 {
1234 #if ENABLE(MEMORY_SAMPLER)
1235     WebMemorySampler::singleton()->stop();
1236 #endif
1237 }
1238
1239 void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState)
1240 {
1241     bool continuousSpellCheckingTurnedOff = !textCheckerState.isContinuousSpellCheckingEnabled && m_textCheckerState.isContinuousSpellCheckingEnabled;
1242     bool grammarCheckingTurnedOff = !textCheckerState.isGrammarCheckingEnabled && m_textCheckerState.isGrammarCheckingEnabled;
1243
1244     m_textCheckerState = textCheckerState;
1245
1246     if (!continuousSpellCheckingTurnedOff && !grammarCheckingTurnedOff)
1247         return;
1248
1249     for (auto& page : m_pageMap.values()) {
1250         if (continuousSpellCheckingTurnedOff)
1251             page->unmarkAllMisspellings();
1252         if (grammarCheckingTurnedOff)
1253             page->unmarkAllBadGrammar();
1254     }
1255 }
1256
1257 void WebProcess::releasePageCache()
1258 {
1259     PageCache::singleton().pruneToSizeNow(0, PruningReason::MemoryPressure);
1260 }
1261
1262 void WebProcess::fetchWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, WebsiteData& websiteData)
1263 {
1264     if (websiteDataTypes.contains(WebsiteDataType::MemoryCache)) {
1265         for (auto& origin : MemoryCache::singleton().originsWithCache(sessionID))
1266             websiteData.entries.append(WebsiteData::Entry { SecurityOriginData::fromSecurityOrigin(*origin), WebsiteDataType::MemoryCache, 0 });
1267     }
1268
1269     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1270         if (NetworkStorageSession::storageSession(sessionID))
1271             websiteData.originsWithCredentials = NetworkStorageSession::storageSession(sessionID)->credentialStorage().originsWithCredentials();
1272     }
1273 }
1274
1275 void WebProcess::deleteWebsiteData(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, WallTime modifiedSince)
1276 {
1277     UNUSED_PARAM(modifiedSince);
1278
1279     if (websiteDataTypes.contains(WebsiteDataType::MemoryCache)) {
1280         PageCache::singleton().pruneToSizeNow(0, PruningReason::None);
1281         MemoryCache::singleton().evictResources(sessionID);
1282
1283         CrossOriginPreflightResultCache::singleton().empty();
1284     }
1285
1286     if (websiteDataTypes.contains(WebsiteDataType::Credentials)) {
1287         if (WebCore::NetworkStorageSession::storageSession(sessionID))
1288             NetworkStorageSession::storageSession(sessionID)->credentialStorage().clearCredentials();
1289     }
1290 }
1291
1292 void WebProcess::deleteWebsiteDataForOrigins(PAL::SessionID sessionID, OptionSet<WebsiteDataType> websiteDataTypes, const Vector<WebCore::SecurityOriginData>& originDatas)
1293 {
1294     if (websiteDataTypes.contains(WebsiteDataType::MemoryCache)) {
1295         HashSet<RefPtr<SecurityOrigin>> origins;
1296         for (auto& originData : originDatas)
1297             origins.add(originData.securityOrigin());
1298
1299         MemoryCache::singleton().removeResourcesWithOrigins(sessionID, origins);
1300     }
1301 }
1302
1303 void WebProcess::setHiddenPageDOMTimerThrottlingIncreaseLimit(int milliseconds)
1304 {
1305     for (auto& page : m_pageMap.values())
1306         page->setHiddenPageDOMTimerThrottlingIncreaseLimit(Seconds::fromMilliseconds(milliseconds));
1307 }
1308
1309 #if !PLATFORM(COCOA)
1310 void WebProcess::initializeProcessName(const ChildProcessInitializationParameters&)
1311 {
1312 }
1313
1314 void WebProcess::initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&)
1315 {
1316 }
1317
1318 void WebProcess::platformInitializeProcess(const ChildProcessInitializationParameters&)
1319 {
1320 }
1321
1322 void WebProcess::updateActivePages()
1323 {
1324 }
1325
1326 void WebProcess::updateCPULimit()
1327 {
1328 }
1329
1330 void WebProcess::updateCPUMonitorState(CPUMonitorUpdateReason)
1331 {
1332 }
1333
1334 #endif
1335
1336 void WebProcess::pageActivityStateDidChange(uint64_t, WebCore::ActivityState::Flags changed)
1337 {
1338     if (changed & WebCore::ActivityState::IsVisible)
1339         updateCPUMonitorState(CPUMonitorUpdateReason::VisibilityHasChanged);
1340 }
1341
1342 #if PLATFORM(IOS)
1343 void WebProcess::resetAllGeolocationPermissions()
1344 {
1345     for (auto& page : m_pageMap.values()) {
1346         if (Frame* mainFrame = page->mainFrame())
1347             mainFrame->resetAllGeolocationPermission();
1348     }
1349 }
1350 #endif
1351
1352 void WebProcess::actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend shouldAcknowledgeWhenReadyToSuspend)
1353 {
1354     if (!m_suppressMemoryPressureHandler)
1355         MemoryPressureHandler::singleton().releaseMemory(Critical::Yes, Synchronous::Yes);
1356
1357     setAllLayerTreeStatesFrozen(true);
1358     
1359 #if PLATFORM(COCOA)
1360     destroyRenderingResources();
1361 #endif
1362
1363 #if PLATFORM(IOS)
1364     accessibilityProcessSuspendedNotification(true);
1365 #endif
1366
1367     markAllLayersVolatile([this, shouldAcknowledgeWhenReadyToSuspend] {
1368         RELEASE_LOG(ProcessSuspension, "%p - WebProcess::markAllLayersVolatile() Successfuly marked all layers as volatile", this);
1369
1370         if (shouldAcknowledgeWhenReadyToSuspend == ShouldAcknowledgeWhenReadyToSuspend::Yes) {
1371             RELEASE_LOG(ProcessSuspension, "%p - WebProcess::actualPrepareToSuspend() Sending ProcessReadyToSuspend IPC message", this);
1372             parentProcessConnection()->send(Messages::WebProcessProxy::ProcessReadyToSuspend(), 0);
1373         }
1374     });
1375 }
1376
1377 void WebProcess::processWillSuspendImminently(bool& handled)
1378 {
1379     if (parentProcessConnection()->inSendSync()) {
1380         // Avoid reentrency bugs such as rdar://problem/21605505 by just bailing
1381         // if we get an incoming ProcessWillSuspendImminently message when waiting for a
1382         // reply to a sync message.
1383         // FIXME: ProcessWillSuspendImminently should not be a sync message.
1384         return;
1385     }
1386
1387     RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processWillSuspendImminently()", this);
1388     DatabaseTracker::singleton().closeAllDatabases(CurrentQueryBehavior::Interrupt);
1389     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::No);
1390     handled = true;
1391 }
1392
1393 void WebProcess::prepareToSuspend()
1394 {
1395     RELEASE_LOG(ProcessSuspension, "%p - WebProcess::prepareToSuspend()", this);
1396     actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend::Yes);
1397 }
1398
1399 void WebProcess::cancelPrepareToSuspend()
1400 {
1401     RELEASE_LOG(ProcessSuspension, "%p - WebProcess::cancelPrepareToSuspend()", this);
1402     setAllLayerTreeStatesFrozen(false);
1403
1404     // If we've already finished cleaning up and sent ProcessReadyToSuspend, we
1405     // shouldn't send DidCancelProcessSuspension; the UI process strictly expects one or the other.
1406     if (!m_pageMarkingLayersAsVolatileCounter)
1407         return;
1408
1409     cancelMarkAllLayersVolatile();
1410     
1411 #if PLATFORM(IOS)
1412     accessibilityProcessSuspendedNotification(false);
1413 #endif
1414
1415     RELEASE_LOG(ProcessSuspension, "%p - WebProcess::cancelPrepareToSuspend() Sending DidCancelProcessSuspension IPC message", this);
1416     parentProcessConnection()->send(Messages::WebProcessProxy::DidCancelProcessSuspension(), 0);
1417 }
1418
1419 void WebProcess::markAllLayersVolatile(WTF::Function<void()>&& completionHandler)
1420 {
1421     RELEASE_LOG(ProcessSuspension, "%p - WebProcess::markAllLayersVolatile()", this);
1422     ASSERT(!m_pageMarkingLayersAsVolatileCounter);
1423     m_pageMarkingLayersAsVolatileCounter = std::make_unique<PageMarkingLayersAsVolatileCounter>([this, completionHandler = WTFMove(completionHandler)] (RefCounterEvent) {
1424         if (m_pageMarkingLayersAsVolatileCounter->value())
1425             return;
1426
1427         completionHandler();
1428         m_pageMarkingLayersAsVolatileCounter = nullptr;
1429     });
1430     auto token = m_pageMarkingLayersAsVolatileCounter->count();
1431     for (auto& page : m_pageMap.values())
1432         page->markLayersVolatile([token] { });
1433 }
1434
1435 void WebProcess::cancelMarkAllLayersVolatile()
1436 {
1437     if (!m_pageMarkingLayersAsVolatileCounter)
1438         return;
1439
1440     m_pageMarkingLayersAsVolatileCounter = nullptr;
1441     for (auto& page : m_pageMap.values())
1442         page->cancelMarkLayersVolatile();
1443 }
1444
1445 void WebProcess::setAllLayerTreeStatesFrozen(bool frozen)
1446 {
1447     for (auto& page : m_pageMap.values())
1448         page->setLayerTreeStateIsFrozen(frozen);
1449 }
1450     
1451 void WebProcess::processDidResume()
1452 {
1453     RELEASE_LOG(ProcessSuspension, "%p - WebProcess::processDidResume()", this);
1454
1455     cancelMarkAllLayersVolatile();
1456     setAllLayerTreeStatesFrozen(false);
1457     
1458 #if PLATFORM(IOS)
1459     accessibilityProcessSuspendedNotification(false);
1460 #endif
1461 }
1462
1463 void WebProcess::pageDidEnterWindow(uint64_t pageID)
1464 {
1465     m_pagesInWindows.add(pageID);
1466     m_nonVisibleProcessCleanupTimer.stop();
1467 }
1468
1469 void WebProcess::pageWillLeaveWindow(uint64_t pageID)
1470 {
1471     m_pagesInWindows.remove(pageID);
1472
1473     if (m_pagesInWindows.isEmpty() && !m_nonVisibleProcessCleanupTimer.isActive())
1474         m_nonVisibleProcessCleanupTimer.startOneShot(nonVisibleProcessCleanupDelay);
1475 }
1476     
1477 void WebProcess::nonVisibleProcessCleanupTimerFired()
1478 {
1479     ASSERT(m_pagesInWindows.isEmpty());
1480     if (!m_pagesInWindows.isEmpty())
1481         return;
1482
1483 #if PLATFORM(COCOA)
1484     destroyRenderingResources();
1485 #endif
1486 }
1487
1488 void WebProcess::setResourceLoadStatisticsEnabled(bool enabled)
1489 {
1490     WebCore::DeprecatedGlobalSettings::setResourceLoadStatisticsEnabled(enabled);
1491 }
1492
1493 void WebProcess::clearResourceLoadStatistics()
1494 {
1495     ResourceLoadObserver::shared().clearState();
1496 }
1497
1498 RefPtr<API::Object> WebProcess::transformHandlesToObjects(API::Object* object)
1499 {
1500     struct Transformer final : UserData::Transformer {
1501         Transformer(WebProcess& webProcess)
1502             : m_webProcess(webProcess)
1503         {
1504         }
1505
1506         bool shouldTransformObject(const API::Object& object) const override
1507         {
1508             switch (object.type()) {
1509             case API::Object::Type::FrameHandle:
1510                 return static_cast<const API::FrameHandle&>(object).isAutoconverting();
1511
1512             case API::Object::Type::PageHandle:
1513                 return static_cast<const API::PageHandle&>(object).isAutoconverting();
1514
1515             case API::Object::Type::PageGroupHandle:
1516 #if PLATFORM(COCOA)
1517             case API::Object::Type::ObjCObjectGraph:
1518 #endif
1519                 return true;
1520
1521             default:
1522                 return false;
1523             }
1524         }
1525
1526         RefPtr<API::Object> transformObject(API::Object& object) const override
1527         {
1528             switch (object.type()) {
1529             case API::Object::Type::FrameHandle:
1530                 return m_webProcess.webFrame(static_cast<const API::FrameHandle&>(object).frameID());
1531
1532             case API::Object::Type::PageGroupHandle:
1533                 return m_webProcess.webPageGroup(static_cast<const API::PageGroupHandle&>(object).webPageGroupData());
1534
1535             case API::Object::Type::PageHandle:
1536                 return m_webProcess.webPage(static_cast<const API::PageHandle&>(object).pageID());
1537
1538 #if PLATFORM(COCOA)
1539             case API::Object::Type::ObjCObjectGraph:
1540                 return m_webProcess.transformHandlesToObjects(static_cast<ObjCObjectGraph&>(object));
1541 #endif
1542             default:
1543                 return &object;
1544             }
1545         }
1546
1547         WebProcess& m_webProcess;
1548     };
1549
1550     return UserData::transform(object, Transformer(*this));
1551 }
1552
1553 RefPtr<API::Object> WebProcess::transformObjectsToHandles(API::Object* object)
1554 {
1555     struct Transformer final : UserData::Transformer {
1556         bool shouldTransformObject(const API::Object& object) const override
1557         {
1558             switch (object.type()) {
1559             case API::Object::Type::BundleFrame:
1560             case API::Object::Type::BundlePage:
1561             case API::Object::Type::BundlePageGroup:
1562 #if PLATFORM(COCOA)
1563             case API::Object::Type::ObjCObjectGraph:
1564 #endif
1565                 return true;
1566
1567             default:
1568                 return false;
1569             }
1570         }
1571
1572         RefPtr<API::Object> transformObject(API::Object& object) const override
1573         {
1574             switch (object.type()) {
1575             case API::Object::Type::BundleFrame:
1576                 return API::FrameHandle::createAutoconverting(static_cast<const WebFrame&>(object).frameID());
1577
1578             case API::Object::Type::BundlePage:
1579                 return API::PageHandle::createAutoconverting(static_cast<const WebPage&>(object).pageID());
1580
1581             case API::Object::Type::BundlePageGroup: {
1582                 WebPageGroupData pageGroupData;
1583                 pageGroupData.pageGroupID = static_cast<const WebPageGroupProxy&>(object).pageGroupID();
1584
1585                 return API::PageGroupHandle::create(WTFMove(pageGroupData));
1586             }
1587
1588 #if PLATFORM(COCOA)
1589             case API::Object::Type::ObjCObjectGraph:
1590                 return transformObjectsToHandles(static_cast<ObjCObjectGraph&>(object));
1591 #endif
1592
1593             default:
1594                 return &object;
1595             }
1596         }
1597     };
1598
1599     return UserData::transform(object, Transformer());
1600 }
1601
1602 void WebProcess::setMemoryCacheDisabled(bool disabled)
1603 {
1604     auto& memoryCache = MemoryCache::singleton();
1605     if (memoryCache.disabled() != disabled)
1606         memoryCache.setDisabled(disabled);
1607 }
1608
1609 #if ENABLE(SERVICE_CONTROLS)
1610 void WebProcess::setEnabledServices(bool hasImageServices, bool hasSelectionServices, bool hasRichContentServices)
1611 {
1612     m_hasImageServices = hasImageServices;
1613     m_hasSelectionServices = hasSelectionServices;
1614     m_hasRichContentServices = hasRichContentServices;
1615 }
1616 #endif
1617
1618 void WebProcess::ensureAutomationSessionProxy(const String& sessionIdentifier)
1619 {
1620     m_automationSessionProxy = std::make_unique<WebAutomationSessionProxy>(sessionIdentifier);
1621 }
1622
1623 void WebProcess::destroyAutomationSessionProxy()
1624 {
1625     m_automationSessionProxy = nullptr;
1626 }
1627
1628 void WebProcess::prefetchDNS(const String& hostname)
1629 {
1630     if (hostname.isEmpty())
1631         return;
1632
1633     if (m_dnsPrefetchedHosts.add(hostname).isNewEntry)
1634         ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::PrefetchDNS(hostname), 0);
1635     // The DNS prefetched hosts cache is only to avoid asking for the same hosts too many times
1636     // in a very short period of time, producing a lot of IPC traffic. So we clear this cache after
1637     // some time of no DNS requests.
1638     m_dnsPrefetchHystereris.impulse();
1639 }
1640
1641 bool WebProcess::hasVisibleWebPage() const
1642 {
1643     for (auto& page : m_pageMap.values()) {
1644         if (page->isVisible())
1645             return true;
1646     }
1647     return false;
1648 }
1649
1650 #if USE(LIBWEBRTC)
1651 LibWebRTCNetwork& WebProcess::libWebRTCNetwork()
1652 {
1653     if (!m_libWebRTCNetwork)
1654         m_libWebRTCNetwork = std::make_unique<LibWebRTCNetwork>();
1655     return *m_libWebRTCNetwork;
1656 }
1657 #endif
1658
1659 #if ENABLE(SERVICE_WORKER)
1660 void WebProcess::establishWorkerContextConnectionToStorageProcess(uint64_t pageGroupID, uint64_t pageID, const WebPreferencesStore& store, PAL::SessionID initialSessionID)
1661 {
1662     // We are in the Service Worker context process and the call below establishes our connection to the Storage Process
1663     // by calling webToStorageProcessConnection. SWContextManager needs to use the same underlying IPC::Connection as the
1664     // WebToStorageProcessConnection for synchronization purposes.
1665     auto& ipcConnection = ensureWebToStorageProcessConnection(initialSessionID).connection();
1666     SWContextManager::singleton().setConnection(std::make_unique<WebSWContextManagerConnection>(ipcConnection, pageGroupID, pageID, store));
1667 }
1668
1669 void WebProcess::registerServiceWorkerClients(PAL::SessionID sessionID)
1670 {
1671     ServiceWorkerProvider::singleton().registerServiceWorkerClients(sessionID);
1672 }
1673
1674 #endif
1675
1676 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
1677 void WebProcess::setScreenProperties(const HashMap<uint32_t, WebCore::ScreenProperties>& properties)
1678 {
1679     WebCore::setScreenProperties(properties);
1680 }
1681 #endif
1682
1683 } // namespace WebKit