1 | /* |
2 | * Copyright (C) 2010-2016 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 | #pragma once |
27 | |
28 | #include "APIDictionary.h" |
29 | #include "APIObject.h" |
30 | #include "APIProcessPoolConfiguration.h" |
31 | #include "APIWebsiteDataStore.h" |
32 | #include "DownloadProxyMap.h" |
33 | #include "GenericCallback.h" |
34 | #include "HiddenPageThrottlingAutoIncreasesCounter.h" |
35 | #include "MessageReceiver.h" |
36 | #include "MessageReceiverMap.h" |
37 | #include "NetworkProcessProxy.h" |
38 | #include "PlugInAutoStartProvider.h" |
39 | #include "PluginInfoStore.h" |
40 | #include "ProcessThrottler.h" |
41 | #include "ServiceWorkerProcessProxy.h" |
42 | #include "StatisticsRequest.h" |
43 | #include "VisitedLinkStore.h" |
44 | #include "WebContextClient.h" |
45 | #include "WebContextConnectionClient.h" |
46 | #include "WebProcessProxy.h" |
47 | #include <WebCore/CrossSiteNavigationDataTransfer.h> |
48 | #include <WebCore/ProcessIdentifier.h> |
49 | #include <WebCore/RegistrableDomain.h> |
50 | #include <WebCore/SecurityOriginHash.h> |
51 | #include <WebCore/SharedStringHash.h> |
52 | #include <pal/SessionID.h> |
53 | #include <wtf/Forward.h> |
54 | #include <wtf/HashMap.h> |
55 | #include <wtf/HashSet.h> |
56 | #include <wtf/MemoryPressureHandler.h> |
57 | #include <wtf/OptionSet.h> |
58 | #include <wtf/RefCounter.h> |
59 | #include <wtf/RefPtr.h> |
60 | #include <wtf/text/StringHash.h> |
61 | #include <wtf/text/WTFString.h> |
62 | |
63 | #if ENABLE(MEDIA_SESSION) |
64 | #include "WebMediaSessionFocusManager.h" |
65 | #endif |
66 | |
67 | #if USE(SOUP) |
68 | #include <WebCore/SoupNetworkProxySettings.h> |
69 | #endif |
70 | |
71 | #if PLATFORM(COCOA) |
72 | OBJC_CLASS NSMutableDictionary; |
73 | OBJC_CLASS NSObject; |
74 | OBJC_CLASS NSString; |
75 | #endif |
76 | |
77 | #if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING) |
78 | #include "DisplayLink.h" |
79 | #endif |
80 | |
81 | namespace API { |
82 | class AutomationClient; |
83 | class CustomProtocolManagerClient; |
84 | class DownloadClient; |
85 | class HTTPCookieStore; |
86 | class InjectedBundleClient; |
87 | class LegacyContextHistoryClient; |
88 | class Navigation; |
89 | class PageConfiguration; |
90 | } |
91 | |
92 | namespace WebCore { |
93 | struct MockMediaDevice; |
94 | } |
95 | |
96 | namespace WebKit { |
97 | |
98 | class DownloadProxy; |
99 | class HighPerformanceGraphicsUsageSampler; |
100 | class UIGamepad; |
101 | class PerActivityStateCPUUsageSampler; |
102 | class ServiceWorkerProcessProxy; |
103 | class WebAutomationSession; |
104 | class WebContextSupplement; |
105 | class WebPageGroup; |
106 | class WebPageProxy; |
107 | class WebProcessCache; |
108 | struct NetworkProcessCreationParameters; |
109 | struct StatisticsData; |
110 | struct WebProcessCreationParameters; |
111 | struct WebProcessDataStoreParameters; |
112 | |
113 | typedef GenericCallback<API::Dictionary*> DictionaryCallback; |
114 | |
115 | #if PLATFORM(COCOA) |
116 | int networkProcessLatencyQOS(); |
117 | int networkProcessThroughputQOS(); |
118 | int webProcessLatencyQOS(); |
119 | int webProcessThroughputQOS(); |
120 | #endif |
121 | |
122 | enum class ProcessSwapRequestedByClient; |
123 | |
124 | class WebProcessPool final : public API::ObjectImpl<API::Object::Type::ProcessPool>, public CanMakeWeakPtr<WebProcessPool>, private IPC::MessageReceiver { |
125 | public: |
126 | static Ref<WebProcessPool> create(API::ProcessPoolConfiguration&); |
127 | |
128 | explicit WebProcessPool(API::ProcessPoolConfiguration&); |
129 | virtual ~WebProcessPool(); |
130 | |
131 | void notifyThisWebProcessPoolWasCreated(); |
132 | |
133 | API::ProcessPoolConfiguration& configuration() { return m_configuration.get(); } |
134 | |
135 | static const Vector<WebProcessPool*>& allProcessPools(); |
136 | |
137 | template <typename T> |
138 | T* supplement() |
139 | { |
140 | return static_cast<T*>(m_supplements.get(T::supplementName())); |
141 | } |
142 | |
143 | template <typename T> |
144 | void addSupplement() |
145 | { |
146 | m_supplements.add(T::supplementName(), T::create(this)); |
147 | } |
148 | |
149 | void addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver&); |
150 | void addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver&); |
151 | void removeMessageReceiver(IPC::StringReference messageReceiverName); |
152 | void removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID); |
153 | |
154 | template <typename T> |
155 | void addMessageReceiver(IPC::StringReference messageReceiverName, ObjectIdentifier<T> destinationID, IPC::MessageReceiver& receiver) |
156 | { |
157 | addMessageReceiver(messageReceiverName, destinationID.toUInt64(), receiver); |
158 | } |
159 | |
160 | template <typename T> |
161 | void removeMessageReceiver(IPC::StringReference messageReceiverName, ObjectIdentifier<T> destinationID) |
162 | { |
163 | removeMessageReceiver(messageReceiverName, destinationID.toUInt64()); |
164 | } |
165 | |
166 | bool dispatchMessage(IPC::Connection&, IPC::Decoder&); |
167 | bool dispatchSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&); |
168 | |
169 | void initializeClient(const WKContextClientBase*); |
170 | void setInjectedBundleClient(std::unique_ptr<API::InjectedBundleClient>&&); |
171 | void initializeConnectionClient(const WKContextConnectionClientBase*); |
172 | void setHistoryClient(std::unique_ptr<API::LegacyContextHistoryClient>&&); |
173 | void setDownloadClient(std::unique_ptr<API::DownloadClient>&&); |
174 | void setAutomationClient(std::unique_ptr<API::AutomationClient>&&); |
175 | void setLegacyCustomProtocolManagerClient(std::unique_ptr<API::CustomProtocolManagerClient>&&); |
176 | |
177 | void setCustomWebContentServiceBundleIdentifier(const String&); |
178 | const String& customWebContentServiceBundleIdentifier() { return m_configuration->customWebContentServiceBundleIdentifier(); } |
179 | |
180 | const Vector<RefPtr<WebProcessProxy>>& processes() const { return m_processes; } |
181 | |
182 | // WebProcessProxy object which does not have a running process which is used for convenience, to avoid |
183 | // null checks in WebPageProxy. |
184 | WebProcessProxy* dummyProcessProxy() const { return m_dummyProcessProxy; } |
185 | |
186 | // WebProcess or NetworkProcess as approporiate for current process model. The connection must be non-null. |
187 | IPC::Connection* networkingProcessConnection(); |
188 | |
189 | template<typename T> void sendToAllProcesses(const T& message); |
190 | template<typename T> void sendToAllProcessesRelaunchingThemIfNecessary(const T& message); |
191 | template<typename T> void sendToOneProcess(T&& message); |
192 | |
193 | // Sends the message to WebProcess or NetworkProcess as approporiate for current process model. |
194 | template<typename T> void sendToNetworkingProcess(T&& message); |
195 | template<typename T, typename U> void sendSyncToNetworkingProcess(T&& message, U&& reply); |
196 | template<typename T> void sendToNetworkingProcessRelaunchingIfNecessary(T&& message); |
197 | |
198 | void processDidFinishLaunching(WebProcessProxy*); |
199 | |
200 | WebProcessCache& webProcessCache() { return m_webProcessCache.get(); } |
201 | |
202 | // Disconnect the process from the context. |
203 | void disconnectProcess(WebProcessProxy*); |
204 | |
205 | API::WebsiteDataStore* websiteDataStore() const { return m_websiteDataStore.get(); } |
206 | void setPrimaryDataStore(API::WebsiteDataStore& dataStore) { m_websiteDataStore = &dataStore; } |
207 | |
208 | Ref<WebPageProxy> createWebPage(PageClient&, Ref<API::PageConfiguration>&&); |
209 | |
210 | void pageBeginUsingWebsiteDataStore(WebCore::PageIdentifier, WebsiteDataStore&); |
211 | void pageEndUsingWebsiteDataStore(WebCore::PageIdentifier, WebsiteDataStore&); |
212 | bool hasPagesUsingWebsiteDataStore(WebsiteDataStore&) const; |
213 | |
214 | const String& injectedBundlePath() const { return m_configuration->injectedBundlePath(); } |
215 | |
216 | DownloadProxy& download(WebPageProxy* initiatingPage, const WebCore::ResourceRequest&, const String& suggestedFilename = { }); |
217 | DownloadProxy& resumeDownload(WebPageProxy* initiatingPage, const API::Data* resumeData, const String& path); |
218 | |
219 | void setInjectedBundleInitializationUserData(RefPtr<API::Object>&& userData) { m_injectedBundleInitializationUserData = WTFMove(userData); } |
220 | |
221 | void postMessageToInjectedBundle(const String&, API::Object*); |
222 | |
223 | void populateVisitedLinks(); |
224 | |
225 | void handleMemoryPressureWarning(Critical); |
226 | |
227 | #if ENABLE(NETSCAPE_PLUGIN_API) |
228 | void setAdditionalPluginsDirectory(const String&); |
229 | void refreshPlugins(); |
230 | |
231 | PluginInfoStore& pluginInfoStore() { return m_pluginInfoStore; } |
232 | |
233 | void setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy, const String& host, const String& bundleIdentifier, const String& versionString); |
234 | void resetPluginLoadClientPolicies(HashMap<String, HashMap<String, HashMap<String, uint8_t>>>&&); |
235 | void clearPluginClientPolicies(); |
236 | const HashMap<String, HashMap<String, HashMap<String, uint8_t>>>& pluginLoadClientPolicies() const { return m_pluginLoadClientPolicies; } |
237 | #endif |
238 | |
239 | #if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING) |
240 | void startDisplayLink(IPC::Connection&, unsigned observerID, uint32_t displayID); |
241 | void stopDisplayLink(IPC::Connection&, unsigned observerID, uint32_t displayID); |
242 | void stopDisplayLinks(IPC::Connection&); |
243 | #endif |
244 | |
245 | void addSupportedPlugin(String&& matchingDomain, String&& name, HashSet<String>&& mimeTypes, HashSet<String> extensions); |
246 | void clearSupportedPlugins(); |
247 | |
248 | ProcessID networkProcessIdentifier(); |
249 | ProcessID prewarmedProcessIdentifier(); |
250 | void activePagesOriginsInWebProcessForTesting(ProcessID, CompletionHandler<void(Vector<String>&&)>&&); |
251 | bool networkProcessHasEntitlementForTesting(const String&); |
252 | |
253 | WebPageGroup& defaultPageGroup() { return m_defaultPageGroup.get(); } |
254 | |
255 | void setAlwaysUsesComplexTextCodePath(bool); |
256 | void setShouldUseFontSmoothing(bool); |
257 | |
258 | void registerURLSchemeAsEmptyDocument(const String&); |
259 | void registerURLSchemeAsSecure(const String&); |
260 | void registerURLSchemeAsBypassingContentSecurityPolicy(const String&); |
261 | void setDomainRelaxationForbiddenForURLScheme(const String&); |
262 | void setCanHandleHTTPSServerTrustEvaluation(bool); |
263 | void registerURLSchemeAsLocal(const String&); |
264 | void registerURLSchemeAsNoAccess(const String&); |
265 | void registerURLSchemeAsDisplayIsolated(const String&); |
266 | void registerURLSchemeAsCORSEnabled(const String&); |
267 | void registerURLSchemeAsCachePartitioned(const String&); |
268 | void registerURLSchemeServiceWorkersCanHandle(const String&); |
269 | void registerURLSchemeAsCanDisplayOnlyIfCanRequest(const String&); |
270 | |
271 | void preconnectToServer(const URL&); |
272 | |
273 | VisitedLinkStore& visitedLinkStore() { return m_visitedLinkStore.get(); } |
274 | |
275 | void setCacheModel(CacheModel); |
276 | CacheModel cacheModel() const { return m_configuration->cacheModel(); } |
277 | |
278 | void setDefaultRequestTimeoutInterval(double); |
279 | |
280 | void startMemorySampler(const double interval); |
281 | void stopMemorySampler(); |
282 | |
283 | #if USE(SOUP) |
284 | void setInitialHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) { m_initialHTTPCookieAcceptPolicy = policy; } |
285 | void setNetworkProxySettings(const WebCore::SoupNetworkProxySettings&); |
286 | #endif |
287 | void setEnhancedAccessibility(bool); |
288 | |
289 | // Downloads. |
290 | DownloadProxy& createDownloadProxy(const WebCore::ResourceRequest&, WebPageProxy* originatingPage); |
291 | API::DownloadClient& downloadClient() { return *m_downloadClient; } |
292 | |
293 | API::LegacyContextHistoryClient& historyClient() { return *m_historyClient; } |
294 | WebContextClient& client() { return m_client; } |
295 | |
296 | API::CustomProtocolManagerClient& customProtocolManagerClient() const { return *m_customProtocolManagerClient; } |
297 | |
298 | struct Statistics { |
299 | unsigned wkViewCount; |
300 | unsigned wkPageCount; |
301 | unsigned wkFrameCount; |
302 | }; |
303 | static Statistics& statistics(); |
304 | |
305 | void useTestingNetworkSession(); |
306 | bool isUsingTestingNetworkSession() const { return m_shouldUseTestingNetworkSession; } |
307 | |
308 | void setAllowsAnySSLCertificateForWebSocket(bool); |
309 | |
310 | void clearCachedCredentials(); |
311 | void terminateNetworkProcess(); |
312 | void sendNetworkProcessWillSuspendImminently(); |
313 | void sendNetworkProcessDidResume(); |
314 | void terminateServiceWorkerProcesses(); |
315 | void disableServiceWorkerProcessTerminationDelay(); |
316 | |
317 | void syncNetworkProcessCookies(); |
318 | |
319 | void setIDBPerOriginQuota(uint64_t); |
320 | |
321 | void setShouldMakeNextWebProcessLaunchFailForTesting(bool value) { m_shouldMakeNextWebProcessLaunchFailForTesting = value; } |
322 | bool shouldMakeNextWebProcessLaunchFailForTesting() const { return m_shouldMakeNextWebProcessLaunchFailForTesting; } |
323 | void setShouldMakeNextNetworkProcessLaunchFailForTesting(bool value) { m_shouldMakeNextNetworkProcessLaunchFailForTesting = value; } |
324 | bool shouldMakeNextNetworkProcessLaunchFailForTesting() const { return m_shouldMakeNextNetworkProcessLaunchFailForTesting; } |
325 | |
326 | void reportWebContentCPUTime(Seconds cpuTime, uint64_t activityState); |
327 | |
328 | void allowSpecificHTTPSCertificateForHost(const WebCertificateInfo*, const String& host); |
329 | |
330 | WebProcessProxy& processForRegistrableDomain(WebsiteDataStore&, WebPageProxy*, const WebCore::RegistrableDomain&); // Will return an existing one if limit is met or due to caching. |
331 | |
332 | void prewarmProcess(); |
333 | |
334 | bool shouldTerminate(WebProcessProxy*); |
335 | |
336 | void disableProcessTermination() { m_processTerminationEnabled = false; } |
337 | void enableProcessTermination(); |
338 | |
339 | void updateAutomationCapabilities() const; |
340 | void setAutomationSession(RefPtr<WebAutomationSession>&&); |
341 | WebAutomationSession* automationSession() const { return m_automationSession.get(); } |
342 | |
343 | // Defaults to false. |
344 | void setHTTPPipeliningEnabled(bool); |
345 | bool httpPipeliningEnabled() const; |
346 | |
347 | void getStatistics(uint32_t statisticsMask, Function<void (API::Dictionary*, CallbackBase::Error)>&&); |
348 | |
349 | bool javaScriptConfigurationFileEnabled() { return m_javaScriptConfigurationFileEnabled; } |
350 | void setJavaScriptConfigurationFileEnabled(bool flag); |
351 | #if PLATFORM(IOS_FAMILY) |
352 | void setJavaScriptConfigurationFileEnabledFromDefaults(); |
353 | #endif |
354 | |
355 | void garbageCollectJavaScriptObjects(); |
356 | void setJavaScriptGarbageCollectorTimerEnabled(bool flag); |
357 | |
358 | #if PLATFORM(COCOA) |
359 | static bool omitPDFSupport(); |
360 | #endif |
361 | |
362 | void fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled); |
363 | #if OS(LINUX) |
364 | void sendMemoryPressureEvent(bool isCritical); |
365 | #endif |
366 | void textCheckerStateChanged(); |
367 | |
368 | Ref<API::Dictionary> plugInAutoStartOriginHashes() const; |
369 | void setPlugInAutoStartOriginHashes(API::Dictionary&); |
370 | void setPlugInAutoStartOrigins(API::Array&); |
371 | void setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary&, WallTime); |
372 | |
373 | // Network Process Management |
374 | NetworkProcessProxy& ensureNetworkProcess(WebsiteDataStore* withWebsiteDataStore = nullptr); |
375 | NetworkProcessProxy* networkProcess() { return m_networkProcess.get(); } |
376 | void networkProcessCrashed(NetworkProcessProxy&, Vector<std::pair<RefPtr<WebProcessProxy>, Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>>&&); |
377 | |
378 | void getNetworkProcessConnection(WebProcessProxy&, Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply&&); |
379 | |
380 | #if ENABLE(SERVICE_WORKER) |
381 | void establishWorkerContextConnectionToNetworkProcess(NetworkProcessProxy&, WebCore::RegistrableDomain&&, Optional<PAL::SessionID>); |
382 | ServiceWorkerProcessProxy* serviceWorkerProcessProxyFromPageID(WebCore::PageIdentifier) const; |
383 | const HashMap<WebCore::RegistrableDomain, ServiceWorkerProcessProxy*>& serviceWorkerProxies() const { return m_serviceWorkerProcesses; } |
384 | void setAllowsAnySSLCertificateForServiceWorker(bool allows) { m_allowsAnySSLCertificateForServiceWorker = allows; } |
385 | bool allowsAnySSLCertificateForServiceWorker() const { return m_allowsAnySSLCertificateForServiceWorker; } |
386 | void updateServiceWorkerUserAgent(const String& userAgent); |
387 | bool mayHaveRegisteredServiceWorkers(const WebsiteDataStore&); |
388 | #endif |
389 | |
390 | #if PLATFORM(COCOA) |
391 | bool processSuppressionEnabled() const; |
392 | #endif |
393 | |
394 | void windowServerConnectionStateChanged(); |
395 | |
396 | static void willStartUsingPrivateBrowsing(); |
397 | static void willStopUsingPrivateBrowsing(); |
398 | |
399 | #if USE(SOUP) |
400 | void setIgnoreTLSErrors(bool); |
401 | bool ignoreTLSErrors() const { return m_ignoreTLSErrors; } |
402 | #endif |
403 | |
404 | static void setInvalidMessageCallback(void (*)(WKStringRef)); |
405 | static void didReceiveInvalidMessage(const IPC::StringReference& messageReceiverName, const IPC::StringReference& messageName); |
406 | |
407 | void processDidCachePage(WebProcessProxy*); |
408 | |
409 | bool isURLKnownHSTSHost(const String& urlString, bool privateBrowsingEnabled) const; |
410 | void resetHSTSHosts(); |
411 | void resetHSTSHostsAddedAfterDate(double startDateIntervalSince1970); |
412 | |
413 | void registerSchemeForCustomProtocol(const String&); |
414 | void unregisterSchemeForCustomProtocol(const String&); |
415 | |
416 | static void registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&); |
417 | static void unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&); |
418 | |
419 | #if PLATFORM(COCOA) |
420 | void updateProcessSuppressionState(); |
421 | |
422 | NSMutableDictionary *ensureBundleParameters(); |
423 | NSMutableDictionary *bundleParameters() { return m_bundleParameters.get(); } |
424 | #else |
425 | void updateProcessSuppressionState() const { } |
426 | #endif |
427 | |
428 | void updateHiddenPageThrottlingAutoIncreaseLimit(); |
429 | |
430 | void setMemoryCacheDisabled(bool); |
431 | void setFontWhitelist(API::Array*); |
432 | |
433 | UserObservablePageCounter::Token userObservablePageCount() |
434 | { |
435 | return m_userObservablePageCounter.count(); |
436 | } |
437 | |
438 | ProcessSuppressionDisabledToken processSuppressionDisabledForPageCount() |
439 | { |
440 | return m_processSuppressionDisabledForPageCounter.count(); |
441 | } |
442 | |
443 | HiddenPageThrottlingAutoIncreasesCounter::Token hiddenPageThrottlingAutoIncreasesCount() |
444 | { |
445 | return m_hiddenPageThrottlingAutoIncreasesCounter.count(); |
446 | } |
447 | |
448 | void setResourceLoadStatisticsEnabled(bool); |
449 | void clearResourceLoadStatistics(); |
450 | |
451 | bool alwaysRunsAtBackgroundPriority() const { return m_alwaysRunsAtBackgroundPriority; } |
452 | bool shouldTakeUIBackgroundAssertion() const { return m_shouldTakeUIBackgroundAssertion; } |
453 | |
454 | void synthesizeAppIsBackground(bool background); |
455 | |
456 | #if ENABLE(GAMEPAD) |
457 | void gamepadConnected(const UIGamepad&); |
458 | void gamepadDisconnected(const UIGamepad&); |
459 | |
460 | void setInitialConnectedGamepads(const Vector<std::unique_ptr<UIGamepad>>&); |
461 | #endif |
462 | |
463 | #if PLATFORM(COCOA) |
464 | bool cookieStoragePartitioningEnabled() const { return m_cookieStoragePartitioningEnabled; } |
465 | void setCookieStoragePartitioningEnabled(bool); |
466 | bool storageAccessAPIEnabled() const { return m_storageAccessAPIEnabled; } |
467 | void setStorageAccessAPIEnabled(bool); |
468 | #endif |
469 | |
470 | #if ENABLE(SERVICE_WORKER) |
471 | void postMessageToServiceWorkerClient(const WebCore::ServiceWorkerClientIdentifier& destinationIdentifier, WebCore::MessageWithMessagePorts&&, WebCore::ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin); |
472 | void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, WebCore::MessageWithMessagePorts&&, const WebCore::ServiceWorkerOrClientIdentifier& source, WebCore::SWServerConnectionIdentifier); |
473 | #endif |
474 | |
475 | static uint64_t registerProcessPoolCreationListener(Function<void(WebProcessPool&)>&&); |
476 | static void unregisterProcessPoolCreationListener(uint64_t identifier); |
477 | |
478 | #if PLATFORM(IOS_FAMILY) |
479 | ForegroundWebProcessToken foregroundWebProcessToken() const { return ForegroundWebProcessToken(m_foregroundWebProcessCounter.count()); } |
480 | BackgroundWebProcessToken backgroundWebProcessToken() const { return BackgroundWebProcessToken(m_backgroundWebProcessCounter.count()); } |
481 | #endif |
482 | |
483 | void processForNavigation(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&); |
484 | |
485 | // SuspendedPageProxy management. |
486 | void addSuspendedPage(std::unique_ptr<SuspendedPageProxy>&&); |
487 | void removeAllSuspendedPagesForPage(WebPageProxy&, WebProcessProxy* = nullptr); |
488 | std::unique_ptr<SuspendedPageProxy> takeSuspendedPage(SuspendedPageProxy&); |
489 | void removeSuspendedPage(SuspendedPageProxy&); |
490 | bool hasSuspendedPageFor(WebProcessProxy&, WebPageProxy&) const; |
491 | unsigned maxSuspendedPageCount() const { return m_maxSuspendedPageCount; } |
492 | RefPtr<WebProcessProxy> findReusableSuspendedPageProcess(const WebCore::RegistrableDomain&, WebPageProxy&, WebsiteDataStore&); |
493 | |
494 | void clearSuspendedPages(AllowProcessCaching); |
495 | |
496 | void didReachGoodTimeToPrewarm(); |
497 | |
498 | void didCollectPrewarmInformation(const WebCore::RegistrableDomain&, const WebCore::PrewarmInformation&); |
499 | |
500 | void screenPropertiesStateChanged(); |
501 | |
502 | void addMockMediaDevice(const WebCore::MockMediaDevice&); |
503 | void clearMockMediaDevices(); |
504 | void removeMockMediaDevice(const String& persistentId); |
505 | void resetMockMediaDevices(); |
506 | |
507 | void sendDisplayConfigurationChangedMessageForTesting(); |
508 | void clearCurrentModifierStateForTesting(); |
509 | |
510 | #if ENABLE(RESOURCE_LOAD_STATISTICS) |
511 | void didCommitCrossSiteLoadWithDataTransfer(PAL::SessionID, const WebCore::RegistrableDomain& fromDomain, const WebCore::RegistrableDomain& toDomain, OptionSet<WebCore::CrossSiteNavigationDataTransfer::Flag>, WebCore::PageIdentifier); |
512 | #endif |
513 | |
514 | #if PLATFORM(GTK) || PLATFORM(WPE) |
515 | void setSandboxEnabled(bool enabled) { m_sandboxEnabled = enabled; }; |
516 | void addSandboxPath(const CString& path, SandboxPermission permission) { m_extraSandboxPaths.add(path, permission); }; |
517 | const HashMap<CString, SandboxPermission>& sandboxPaths() const { return m_extraSandboxPaths; }; |
518 | bool sandboxEnabled() const { return m_sandboxEnabled; }; |
519 | #endif |
520 | |
521 | void setWebProcessHasUploads(WebCore::ProcessIdentifier); |
522 | void clearWebProcessHasUploads(WebCore::ProcessIdentifier); |
523 | |
524 | void setWebProcessIsPlayingAudibleMedia(WebCore::ProcessIdentifier); |
525 | void clearWebProcessIsPlayingAudibleMedia(WebCore::ProcessIdentifier); |
526 | |
527 | void disableDelayedWebProcessLaunch() { m_isDelayedWebProcessLaunchDisabled = true; } |
528 | |
529 | private: |
530 | void platformInitialize(); |
531 | |
532 | void platformInitializeWebProcess(WebProcessCreationParameters&); |
533 | void platformInvalidateContext(); |
534 | |
535 | void processForNavigationInternal(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&); |
536 | |
537 | RefPtr<WebProcessProxy> tryTakePrewarmedProcess(WebsiteDataStore&); |
538 | |
539 | WebProcessProxy& createNewWebProcess(WebsiteDataStore*, WebProcessProxy::IsPrewarmed = WebProcessProxy::IsPrewarmed::No); |
540 | void initializeNewWebProcess(WebProcessProxy&, WebsiteDataStore*, WebProcessProxy::IsPrewarmed = WebProcessProxy::IsPrewarmed::No); |
541 | void sendWebProcessDataStoreParameters(WebProcessProxy&, WebsiteDataStore&); |
542 | |
543 | void requestWebContentStatistics(StatisticsRequest&); |
544 | void requestNetworkingStatistics(StatisticsRequest&); |
545 | |
546 | void platformInitializeNetworkProcess(NetworkProcessCreationParameters&); |
547 | |
548 | void handleMessage(IPC::Connection&, const String& messageName, const UserData& messageBody); |
549 | void handleSynchronousMessage(IPC::Connection&, const String& messageName, const UserData& messageBody, CompletionHandler<void(UserData&&)>&&); |
550 | |
551 | void didGetStatistics(const StatisticsData&, uint64_t callbackID); |
552 | |
553 | #if ENABLE(GAMEPAD) |
554 | void startedUsingGamepads(IPC::Connection&); |
555 | void stoppedUsingGamepads(IPC::Connection&); |
556 | |
557 | void processStoppedUsingGamepads(WebProcessProxy&); |
558 | #endif |
559 | |
560 | void reinstateNetworkProcessAssertionState(NetworkProcessProxy&); |
561 | void updateProcessAssertions(); |
562 | |
563 | // IPC::MessageReceiver. |
564 | // Implemented in generated WebProcessPoolMessageReceiver.cpp |
565 | void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override; |
566 | void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override; |
567 | |
568 | static void languageChanged(void* context); |
569 | void languageChanged(); |
570 | |
571 | bool usesSingleWebProcess() const { return m_configuration->usesSingleWebProcess(); } |
572 | |
573 | #if PLATFORM(IOS_FAMILY) |
574 | String cookieStorageDirectory() const; |
575 | #endif |
576 | |
577 | #if PLATFORM(IOS_FAMILY) |
578 | String parentBundleDirectory() const; |
579 | String networkingCachesDirectory() const; |
580 | String webContentCachesDirectory() const; |
581 | String containerTemporaryDirectory() const; |
582 | #endif |
583 | |
584 | #if PLATFORM(COCOA) |
585 | void registerNotificationObservers(); |
586 | void unregisterNotificationObservers(); |
587 | #endif |
588 | |
589 | void setApplicationIsActive(bool); |
590 | |
591 | void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, PAL::SessionID); |
592 | void plugInDidReceiveUserInteraction(unsigned plugInOriginHash, PAL::SessionID); |
593 | |
594 | void setAnyPageGroupMightHavePrivateBrowsingEnabled(bool); |
595 | |
596 | void resolvePathsForSandboxExtensions(); |
597 | void platformResolvePathsForSandboxExtensions(); |
598 | |
599 | void addProcessToOriginCacheSet(WebProcessProxy&, const URL&); |
600 | void removeProcessFromOriginCacheSet(WebProcessProxy&); |
601 | |
602 | void tryPrewarmWithDomainInformation(WebProcessProxy&, const WebCore::RegistrableDomain&); |
603 | |
604 | void updateMaxSuspendedPageCount(); |
605 | |
606 | #if PLATFORM(IOS) |
607 | static float displayBrightness(); |
608 | static void backlightLevelDidChangeCallback(CFNotificationCenterRef, void *observer, CFStringRef name, const void *, CFDictionaryRef userInfo); |
609 | #endif |
610 | |
611 | Ref<API::ProcessPoolConfiguration> m_configuration; |
612 | |
613 | IPC::MessageReceiverMap m_messageReceiverMap; |
614 | |
615 | Vector<RefPtr<WebProcessProxy>> m_processes; |
616 | WebProcessProxy* m_prewarmedProcess { nullptr }; |
617 | WebProcessProxy* m_dummyProcessProxy { nullptr }; // A lightweight WebProcessProxy without backing process. |
618 | |
619 | WebProcessProxy* m_processWithPageCache { nullptr }; |
620 | #if ENABLE(SERVICE_WORKER) |
621 | HashMap<WebCore::RegistrableDomain, ServiceWorkerProcessProxy*> m_serviceWorkerProcesses; |
622 | bool m_waitingForWorkerContextProcessConnection { false }; |
623 | bool m_allowsAnySSLCertificateForServiceWorker { false }; |
624 | bool m_shouldDisableServiceWorkerProcessTerminationDelay { false }; |
625 | String m_serviceWorkerUserAgent; |
626 | Optional<WebPreferencesStore> m_serviceWorkerPreferences; |
627 | HashMap<String, bool> m_mayHaveRegisteredServiceWorkers; |
628 | #endif |
629 | |
630 | Ref<WebPageGroup> m_defaultPageGroup; |
631 | |
632 | RefPtr<API::Object> m_injectedBundleInitializationUserData; |
633 | std::unique_ptr<API::InjectedBundleClient> m_injectedBundleClient; |
634 | |
635 | WebContextClient m_client; |
636 | WebContextConnectionClient m_connectionClient; |
637 | std::unique_ptr<API::AutomationClient> m_automationClient; |
638 | std::unique_ptr<API::DownloadClient> m_downloadClient; |
639 | std::unique_ptr<API::LegacyContextHistoryClient> m_historyClient; |
640 | std::unique_ptr<API::CustomProtocolManagerClient> m_customProtocolManagerClient; |
641 | |
642 | RefPtr<WebAutomationSession> m_automationSession; |
643 | |
644 | #if ENABLE(NETSCAPE_PLUGIN_API) |
645 | PluginInfoStore m_pluginInfoStore; |
646 | #endif |
647 | Ref<VisitedLinkStore> m_visitedLinkStore; |
648 | bool m_visitedLinksPopulated { false }; |
649 | |
650 | PlugInAutoStartProvider m_plugInAutoStartProvider { this }; |
651 | |
652 | HashSet<String> m_schemesToRegisterAsEmptyDocument; |
653 | HashSet<String> m_schemesToRegisterAsSecure; |
654 | HashSet<String> m_schemesToRegisterAsBypassingContentSecurityPolicy; |
655 | HashSet<String> m_schemesToSetDomainRelaxationForbiddenFor; |
656 | HashSet<String> m_schemesToRegisterAsLocal; |
657 | HashSet<String> m_schemesToRegisterAsNoAccess; |
658 | HashSet<String> m_schemesToRegisterAsDisplayIsolated; |
659 | HashSet<String> m_schemesToRegisterAsCORSEnabled; |
660 | HashSet<String> m_schemesToRegisterAsAlwaysRevalidated; |
661 | HashSet<String> m_schemesToRegisterAsCachePartitioned; |
662 | HashSet<String> m_schemesServiceWorkersCanHandle; |
663 | HashSet<String> m_schemesToRegisterAsCanDisplayOnlyIfCanRequest; |
664 | |
665 | bool m_alwaysUsesComplexTextCodePath { false }; |
666 | bool m_shouldUseFontSmoothing { true }; |
667 | |
668 | Vector<String> m_fontWhitelist; |
669 | |
670 | // Messages that were posted before any pages were created. |
671 | // The client should use initialization messages instead, so that a restarted process would get the same state. |
672 | Vector<std::pair<String, RefPtr<API::Object>>> m_messagesToInjectedBundlePostedToEmptyContext; |
673 | |
674 | bool m_memorySamplerEnabled { false }; |
675 | double m_memorySamplerInterval { 1400.0 }; |
676 | |
677 | RefPtr<API::WebsiteDataStore> m_websiteDataStore; |
678 | |
679 | typedef HashMap<const char*, RefPtr<WebContextSupplement>, PtrHash<const char*>> WebContextSupplementMap; |
680 | WebContextSupplementMap m_supplements; |
681 | |
682 | #if USE(SOUP) |
683 | HTTPCookieAcceptPolicy m_initialHTTPCookieAcceptPolicy { HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain }; |
684 | WebCore::SoupNetworkProxySettings m_networkProxySettings; |
685 | #endif |
686 | HashSet<String, ASCIICaseInsensitiveHash> m_urlSchemesRegisteredForCustomProtocols; |
687 | |
688 | #if PLATFORM(MAC) |
689 | RetainPtr<NSObject> m_enhancedAccessibilityObserver; |
690 | RetainPtr<NSObject> m_automaticTextReplacementNotificationObserver; |
691 | RetainPtr<NSObject> m_automaticSpellingCorrectionNotificationObserver; |
692 | RetainPtr<NSObject> m_automaticQuoteSubstitutionNotificationObserver; |
693 | RetainPtr<NSObject> m_automaticDashSubstitutionNotificationObserver; |
694 | RetainPtr<NSObject> m_accessibilityDisplayOptionsNotificationObserver; |
695 | #if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING) |
696 | RetainPtr<NSObject> m_scrollerStyleNotificationObserver; |
697 | #endif |
698 | RetainPtr<NSObject> m_activationObserver; |
699 | RetainPtr<NSObject> m_deactivationObserver; |
700 | |
701 | std::unique_ptr<HighPerformanceGraphicsUsageSampler> m_highPerformanceGraphicsUsageSampler; |
702 | std::unique_ptr<PerActivityStateCPUUsageSampler> m_perActivityStateCPUUsageSampler; |
703 | #endif |
704 | |
705 | #if PLATFORM(IOS_FAMILY) |
706 | RetainPtr<NSObject> m_accessibilityEnabledObserver; |
707 | #endif |
708 | |
709 | bool m_shouldUseTestingNetworkSession { false }; |
710 | |
711 | bool m_processTerminationEnabled { true }; |
712 | |
713 | bool m_canHandleHTTPSServerTrustEvaluation { true }; |
714 | bool m_didNetworkProcessCrash { false }; |
715 | std::unique_ptr<NetworkProcessProxy> m_networkProcess; |
716 | |
717 | HashMap<uint64_t, RefPtr<DictionaryCallback>> m_dictionaryCallbacks; |
718 | HashMap<uint64_t, RefPtr<StatisticsRequest>> m_statisticsRequests; |
719 | |
720 | #if USE(SOUP) |
721 | bool m_ignoreTLSErrors { true }; |
722 | #endif |
723 | |
724 | bool m_memoryCacheDisabled { false }; |
725 | bool m_javaScriptConfigurationFileEnabled { false }; |
726 | bool m_alwaysRunsAtBackgroundPriority; |
727 | bool m_shouldTakeUIBackgroundAssertion; |
728 | bool m_shouldMakeNextWebProcessLaunchFailForTesting { false }; |
729 | bool m_shouldMakeNextNetworkProcessLaunchFailForTesting { false }; |
730 | |
731 | UserObservablePageCounter m_userObservablePageCounter; |
732 | ProcessSuppressionDisabledCounter m_processSuppressionDisabledForPageCounter; |
733 | HiddenPageThrottlingAutoIncreasesCounter m_hiddenPageThrottlingAutoIncreasesCounter; |
734 | RunLoop::Timer<WebProcessPool> m_hiddenPageThrottlingTimer; |
735 | |
736 | #if PLATFORM(COCOA) |
737 | RetainPtr<NSMutableDictionary> m_bundleParameters; |
738 | ProcessSuppressionDisabledToken m_pluginProcessManagerProcessSuppressionDisabledToken; |
739 | #endif |
740 | |
741 | #if ENABLE(CONTENT_EXTENSIONS) |
742 | HashMap<String, String> m_encodedContentExtensions; |
743 | #endif |
744 | |
745 | #if ENABLE(NETSCAPE_PLUGIN_API) |
746 | HashMap<String, HashMap<String, HashMap<String, uint8_t>>> m_pluginLoadClientPolicies; |
747 | #endif |
748 | |
749 | #if ENABLE(GAMEPAD) |
750 | HashSet<WebProcessProxy*> m_processesUsingGamepads; |
751 | #endif |
752 | |
753 | #if PLATFORM(COCOA) |
754 | bool m_cookieStoragePartitioningEnabled { false }; |
755 | bool m_storageAccessAPIEnabled { false }; |
756 | #endif |
757 | |
758 | struct Paths { |
759 | String injectedBundlePath; |
760 | String applicationCacheDirectory; |
761 | String webSQLDatabaseDirectory; |
762 | String mediaCacheDirectory; |
763 | String mediaKeyStorageDirectory; |
764 | String uiProcessBundleResourcePath; |
765 | String indexedDatabaseDirectory; |
766 | |
767 | #if PLATFORM(IOS_FAMILY) |
768 | String cookieStorageDirectory; |
769 | String containerCachesDirectory; |
770 | String containerTemporaryDirectory; |
771 | #endif |
772 | |
773 | Vector<String> additionalWebProcessSandboxExtensionPaths; |
774 | }; |
775 | Paths m_resolvedPaths; |
776 | |
777 | HashMap<PAL::SessionID, HashSet<WebCore::PageIdentifier>> m_sessionToPageIDsMap; |
778 | RunLoop::Timer<WebProcessPool> m_serviceWorkerProcessesTerminationTimer; |
779 | |
780 | #if PLATFORM(IOS_FAMILY) |
781 | ForegroundWebProcessCounter m_foregroundWebProcessCounter; |
782 | BackgroundWebProcessCounter m_backgroundWebProcessCounter; |
783 | ProcessThrottler::ForegroundActivityToken m_foregroundTokenForNetworkProcess; |
784 | ProcessThrottler::BackgroundActivityToken m_backgroundTokenForNetworkProcess; |
785 | #if ENABLE(SERVICE_WORKER) |
786 | HashMap<WebCore::RegistrableDomain, ProcessThrottler::ForegroundActivityToken> m_foregroundTokensForServiceWorkerProcesses; |
787 | HashMap<WebCore::RegistrableDomain, ProcessThrottler::BackgroundActivityToken> m_backgroundTokensForServiceWorkerProcesses; |
788 | #endif |
789 | #endif |
790 | |
791 | Deque<std::unique_ptr<SuspendedPageProxy>> m_suspendedPages; |
792 | unsigned m_maxSuspendedPageCount { 0 }; |
793 | |
794 | UniqueRef<WebProcessCache> m_webProcessCache; |
795 | HashMap<WebCore::RegistrableDomain, RefPtr<WebProcessProxy>> m_swappedProcessesPerRegistrableDomain; |
796 | |
797 | HashMap<WebCore::RegistrableDomain, std::unique_ptr<WebCore::PrewarmInformation>> m_prewarmInformationPerRegistrableDomain; |
798 | |
799 | #if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING) |
800 | Vector<std::unique_ptr<DisplayLink>> m_displayLinks; |
801 | #endif |
802 | |
803 | #if PLATFORM(GTK) || PLATFORM(WPE) |
804 | bool m_sandboxEnabled { false }; |
805 | HashMap<CString, SandboxPermission> m_extraSandboxPaths; |
806 | #endif |
807 | |
808 | HashMap<WebCore::ProcessIdentifier, std::unique_ptr<ProcessAssertion>> m_processesWithUploads; |
809 | std::unique_ptr<ProcessAssertion> m_uiProcessUploadAssertion; |
810 | |
811 | HashMap<WebCore::ProcessIdentifier, std::unique_ptr<ProcessAssertion>> m_processesPlayingAudibleMedia; |
812 | std::unique_ptr<ProcessAssertion> m_uiProcessMediaPlaybackAssertion; |
813 | |
814 | #if PLATFORM(IOS) |
815 | // FIXME: Delayed process launch is currently disabled on iOS for performance reasons (rdar://problem/49074131). |
816 | bool m_isDelayedWebProcessLaunchDisabled { true }; |
817 | #else |
818 | bool m_isDelayedWebProcessLaunchDisabled { false }; |
819 | #endif |
820 | }; |
821 | |
822 | template<typename T> |
823 | void WebProcessPool::sendToNetworkingProcess(T&& message) |
824 | { |
825 | if (m_networkProcess && m_networkProcess->canSendMessage()) |
826 | m_networkProcess->send(std::forward<T>(message), 0); |
827 | } |
828 | |
829 | template<typename T> |
830 | void WebProcessPool::sendToNetworkingProcessRelaunchingIfNecessary(T&& message) |
831 | { |
832 | ensureNetworkProcess(); |
833 | m_networkProcess->send(std::forward<T>(message), 0); |
834 | } |
835 | |
836 | template<typename T> |
837 | void WebProcessPool::sendToAllProcesses(const T& message) |
838 | { |
839 | size_t processCount = m_processes.size(); |
840 | for (size_t i = 0; i < processCount; ++i) { |
841 | WebProcessProxy* process = m_processes[i].get(); |
842 | if (process->canSendMessage()) |
843 | process->send(T(message), 0); |
844 | } |
845 | } |
846 | |
847 | template<typename T> |
848 | void WebProcessPool::sendToAllProcessesRelaunchingThemIfNecessary(const T& message) |
849 | { |
850 | // FIXME (Multi-WebProcess): WebProcessPool doesn't track processes that have exited, so it cannot relaunch these. Perhaps this functionality won't be needed in this mode. |
851 | sendToAllProcesses(message); |
852 | } |
853 | |
854 | template<typename T> |
855 | void WebProcessPool::sendToOneProcess(T&& message) |
856 | { |
857 | bool messageSent = false; |
858 | size_t processCount = m_processes.size(); |
859 | for (size_t i = 0; i < processCount; ++i) { |
860 | WebProcessProxy* process = m_processes[i].get(); |
861 | if (process->canSendMessage()) { |
862 | process->send(std::forward<T>(message), 0); |
863 | messageSent = true; |
864 | break; |
865 | } |
866 | } |
867 | |
868 | if (!messageSent) { |
869 | prewarmProcess(); |
870 | RefPtr<WebProcessProxy> process = m_processes.last(); |
871 | if (process->canSendMessage()) |
872 | process->send(std::forward<T>(message), 0); |
873 | } |
874 | } |
875 | |
876 | } // namespace WebKit |
877 | |