1/*
2 * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "AuxiliaryProcess.h"
29#include "CacheModel.h"
30#if ENABLE(MEDIA_STREAM)
31#include "MediaDeviceSandboxExtensions.h"
32#endif
33#include "PluginProcessConnectionManager.h"
34#include "ResourceCachesToClear.h"
35#include "SandboxExtension.h"
36#include "TextCheckerState.h"
37#include "ViewUpdateDispatcher.h"
38#include "WebInspectorInterruptDispatcher.h"
39#include "WebProcessCreationParameters.h"
40#include "WebSQLiteDatabaseTracker.h"
41#include <WebCore/ActivityState.h>
42#include <WebCore/RegistrableDomain.h>
43#if PLATFORM(MAC)
44#include <WebCore/ScreenProperties.h>
45#endif
46#include <WebCore/Timer.h>
47#include <pal/HysteresisActivity.h>
48#include <pal/SessionID.h>
49#include <wtf/Forward.h>
50#include <wtf/HashMap.h>
51#include <wtf/HashSet.h>
52#include <wtf/RefCounter.h>
53#include <wtf/text/AtomicString.h>
54#include <wtf/text/AtomicStringHash.h>
55
56#if PLATFORM(COCOA)
57#include <dispatch/dispatch.h>
58#include <wtf/MachSendRight.h>
59#endif
60
61#if PLATFORM(IOS_FAMILY)
62#include "ProcessTaskStateObserver.h"
63#endif
64
65namespace API {
66class Object;
67}
68
69namespace PAL {
70class SessionID;
71}
72
73namespace WebCore {
74class ApplicationCacheStorage;
75class CPUMonitor;
76class CertificateInfo;
77class PageGroup;
78class ResourceRequest;
79class UserGestureToken;
80struct MessagePortIdentifier;
81struct MessageWithMessagePorts;
82struct MockMediaDevice;
83struct PluginInfo;
84struct PrewarmInformation;
85struct SecurityOriginData;
86
87#if ENABLE(SERVICE_WORKER)
88struct ServiceWorkerContextData;
89#endif
90}
91
92namespace WebKit {
93
94class EventDispatcher;
95class GamepadData;
96class InjectedBundle;
97class LibWebRTCNetwork;
98class NetworkProcessConnection;
99class ObjCObjectGraph;
100class UserData;
101class WaylandCompositorDisplay;
102class WebAutomationSessionProxy;
103class WebCacheStorageProvider;
104class WebConnectionToUIProcess;
105class WebFrame;
106class WebLoaderStrategy;
107class WebPage;
108class WebPageGroupProxy;
109struct WebProcessCreationParameters;
110struct WebProcessDataStoreParameters;
111class WebProcessSupplement;
112enum class WebsiteDataType;
113struct WebPageCreationParameters;
114struct WebPageGroupData;
115struct WebPreferencesStore;
116struct WebsiteData;
117struct WebsiteDataStoreParameters;
118
119#if PLATFORM(IOS_FAMILY)
120class LayerHostingContext;
121#endif
122
123class WebProcess
124 : public AuxiliaryProcess
125#if PLATFORM(IOS_FAMILY)
126 , ProcessTaskStateObserver::Client
127#endif
128{
129public:
130 static WebProcess& singleton();
131 static constexpr ProcessType processType = ProcessType::WebContent;
132
133 template <typename T>
134 T* supplement()
135 {
136 return static_cast<T*>(m_supplements.get(T::supplementName()));
137 }
138
139 template <typename T>
140 void addSupplement()
141 {
142 m_supplements.add(T::supplementName(), std::make_unique<T>(*this));
143 }
144
145 WebConnectionToUIProcess* webConnectionToUIProcess() const { return m_webConnection.get(); }
146
147 WebPage* webPage(uint64_t pageID) const;
148 void createWebPage(uint64_t pageID, WebPageCreationParameters&&);
149 void removeWebPage(uint64_t pageID);
150 WebPage* focusedWebPage() const;
151
152 InjectedBundle* injectedBundle() const { return m_injectedBundle.get(); }
153
154#if PLATFORM(COCOA)
155 const WTF::MachSendRight& compositingRenderServerPort() const { return m_compositingRenderServerPort; }
156#endif
157
158 bool shouldPlugInAutoStartFromOrigin(WebPage&, const String& pageOrigin, const String& pluginOrigin, const String& mimeType);
159 void plugInDidStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType, PAL::SessionID);
160 void plugInDidReceiveUserInteraction(const String& pageOrigin, const String& pluginOrigin, const String& mimeType, PAL::SessionID);
161 void setPluginLoadClientPolicy(uint8_t policy, const String& host, const String& bundleIdentifier, const String& versionString);
162 void resetPluginLoadClientPolicies(const HashMap<String, HashMap<String, HashMap<String, uint8_t>>>&);
163 void clearPluginClientPolicies();
164 void refreshPlugins();
165
166 bool fullKeyboardAccessEnabled() const { return m_fullKeyboardAccessEnabled; }
167
168 WebFrame* webFrame(uint64_t) const;
169 void addWebFrame(uint64_t, WebFrame*);
170 void removeWebFrame(uint64_t);
171
172 WebPageGroupProxy* webPageGroup(WebCore::PageGroup*);
173 WebPageGroupProxy* webPageGroup(uint64_t pageGroupID);
174 WebPageGroupProxy* webPageGroup(const WebPageGroupData&);
175
176 uint64_t userGestureTokenIdentifier(RefPtr<WebCore::UserGestureToken>);
177 void userGestureTokenDestroyed(WebCore::UserGestureToken&);
178
179 const TextCheckerState& textCheckerState() const { return m_textCheckerState; }
180 void setTextCheckerState(const TextCheckerState&);
181
182 void clearResourceCaches(ResourceCachesToClear = AllResourceCaches);
183
184#if ENABLE(NETSCAPE_PLUGIN_API)
185 PluginProcessConnectionManager& pluginProcessConnectionManager();
186#endif
187
188 EventDispatcher& eventDispatcher() { return m_eventDispatcher.get(); }
189
190 NetworkProcessConnection& ensureNetworkProcessConnection();
191 void networkProcessConnectionClosed(NetworkProcessConnection*);
192 NetworkProcessConnection* existingNetworkProcessConnection() { return m_networkProcessConnection.get(); }
193 WebLoaderStrategy& webLoaderStrategy();
194
195 LibWebRTCNetwork& libWebRTCNetwork();
196
197 void setCacheModel(CacheModel);
198
199 void ensureLegacyPrivateBrowsingSessionInNetworkProcess();
200
201 void pageDidEnterWindow(uint64_t pageID);
202 void pageWillLeaveWindow(uint64_t pageID);
203
204 void nonVisibleProcessCleanupTimerFired();
205
206#if PLATFORM(COCOA)
207 RetainPtr<CFDataRef> sourceApplicationAuditData() const;
208 void destroyRenderingResources();
209#endif
210
211 const String& uiProcessBundleIdentifier() const { return m_uiProcessBundleIdentifier; }
212
213 void updateActivePages();
214 void getActivePagesOriginsForTesting(CompletionHandler<void(Vector<String>&&)>&&);
215 void pageActivityStateDidChange(uint64_t pageID, OptionSet<WebCore::ActivityState::Flag> changed);
216
217 void setHiddenPageDOMTimerThrottlingIncreaseLimit(int milliseconds);
218
219 void processWillSuspendImminently();
220 void prepareToSuspend();
221 void cancelPrepareToSuspend();
222 void processDidResume();
223
224 void sendPrewarmInformation(const URL&);
225
226 void isJITEnabled(CompletionHandler<void(bool)>&&);
227
228#if PLATFORM(IOS_FAMILY)
229 void resetAllGeolocationPermissions();
230#endif
231
232#if PLATFORM(WAYLAND)
233 WaylandCompositorDisplay* waylandCompositorDisplay() const { return m_waylandCompositorDisplay.get(); }
234#endif
235
236 RefPtr<API::Object> transformHandlesToObjects(API::Object*);
237 static RefPtr<API::Object> transformObjectsToHandles(API::Object*);
238
239#if PLATFORM(COCOA)
240 RefPtr<ObjCObjectGraph> transformHandlesToObjects(ObjCObjectGraph&);
241 static RefPtr<ObjCObjectGraph> transformObjectsToHandles(ObjCObjectGraph&);
242#endif
243
244#if ENABLE(SERVICE_CONTROLS)
245 bool hasImageServices() const { return m_hasImageServices; }
246 bool hasSelectionServices() const { return m_hasSelectionServices; }
247 bool hasRichContentServices() const { return m_hasRichContentServices; }
248#endif
249
250 WebCore::ApplicationCacheStorage& applicationCacheStorage() { return *m_applicationCacheStorage; }
251
252 void prefetchDNS(const String&);
253
254 WebAutomationSessionProxy* automationSessionProxy() { return m_automationSessionProxy.get(); }
255
256 WebCacheStorageProvider& cacheStorageProvider() { return m_cacheStorageProvider.get(); }
257
258#if PLATFORM(IOS_FAMILY)
259 void accessibilityProcessSuspendedNotification(bool);
260
261 void unblockAccessibilityServer(const SandboxExtension::Handle&);
262#endif
263
264#if PLATFORM(IOS)
265 float backlightLevel() const { return m_backlightLevel; }
266#endif
267
268#if PLATFORM(COCOA)
269 void setMediaMIMETypes(const Vector<String>);
270#endif
271
272 bool areAllPagesThrottleable() const;
273
274private:
275 WebProcess();
276 ~WebProcess();
277
278 void initializeWebProcess(WebProcessCreationParameters&&);
279 void platformInitializeWebProcess(WebProcessCreationParameters&);
280 void setWebsiteDataStoreParameters(WebProcessDataStoreParameters&&);
281 void platformSetWebsiteDataStoreParameters(WebProcessDataStoreParameters&&);
282
283 void prewarmGlobally();
284 void prewarmWithDomainInformation(const WebCore::PrewarmInformation&);
285
286#if USE(OS_STATE)
287 void registerWithStateDumper();
288#endif
289
290 void markAllLayersVolatile(WTF::Function<void(bool)>&& completionHandler);
291 void cancelMarkAllLayersVolatile();
292
293 void freezeAllLayerTrees();
294 void unfreezeAllLayerTrees();
295
296 void processSuspensionCleanupTimerFired();
297
298 void platformTerminate();
299
300 void setHasSuspendedPageProxy(bool);
301 void setIsInProcessCache(bool);
302 void markIsNoLongerPrewarmed();
303
304 void registerURLSchemeAsEmptyDocument(const String&);
305 void registerURLSchemeAsSecure(const String&) const;
306 void registerURLSchemeAsBypassingContentSecurityPolicy(const String&) const;
307 void setDomainRelaxationForbiddenForURLScheme(const String&) const;
308 void registerURLSchemeAsLocal(const String&) const;
309 void registerURLSchemeAsNoAccess(const String&) const;
310 void registerURLSchemeAsDisplayIsolated(const String&) const;
311 void registerURLSchemeAsCORSEnabled(const String&) const;
312 void registerURLSchemeAsAlwaysRevalidated(const String&) const;
313 void registerURLSchemeAsCachePartitioned(const String&) const;
314 void registerURLSchemeAsCanDisplayOnlyIfCanRequest(const String&) const;
315
316 void setDefaultRequestTimeoutInterval(double);
317 void setAlwaysUsesComplexTextCodePath(bool);
318 void setShouldUseFontSmoothing(bool);
319 void setResourceLoadStatisticsEnabled(bool);
320 void clearResourceLoadStatistics();
321 void userPreferredLanguagesChanged(const Vector<String>&) const;
322 void fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled);
323
324 bool isPlugInAutoStartOriginHash(unsigned plugInOriginHash, PAL::SessionID);
325 void didAddPlugInAutoStartOriginHash(unsigned plugInOriginHash, WallTime expirationTime, PAL::SessionID);
326 void resetPlugInAutoStartOriginDefaultHashes(const HashMap<unsigned, WallTime>& hashes);
327 void resetPlugInAutoStartOriginHashes(const HashMap<PAL::SessionID, HashMap<unsigned, WallTime>>& hashes);
328
329 void platformSetCacheModel(CacheModel);
330
331 void setEnhancedAccessibility(bool);
332
333 void startMemorySampler(SandboxExtension::Handle&&, const String&, const double);
334 void stopMemorySampler();
335
336 void getWebCoreStatistics(uint64_t callbackID);
337 void garbageCollectJavaScriptObjects();
338 void setJavaScriptGarbageCollectorTimerEnabled(bool flag);
339
340 void mainThreadPing();
341 void backgroundResponsivenessPing();
342
343 void didTakeAllMessagesForPort(Vector<WebCore::MessageWithMessagePorts>&& messages, uint64_t messageCallbackIdentifier, uint64_t messageBatchIdentifier);
344 void checkProcessLocalPortForActivity(const WebCore::MessagePortIdentifier&, uint64_t callbackIdentifier);
345 void didCheckRemotePortForActivity(uint64_t callbackIdentifier, bool hasActivity);
346 void messagesAvailableForPort(const WebCore::MessagePortIdentifier&);
347
348#if ENABLE(GAMEPAD)
349 void setInitialGamepads(const Vector<GamepadData>&);
350 void gamepadConnected(const GamepadData&);
351 void gamepadDisconnected(unsigned index);
352#endif
353
354#if ENABLE(SERVICE_WORKER)
355 void establishWorkerContextConnectionToNetworkProcess(uint64_t pageGroupID, uint64_t pageID, const WebPreferencesStore&, PAL::SessionID);
356 void registerServiceWorkerClients();
357#endif
358
359 void releasePageCache();
360
361 void fetchWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, CompletionHandler<void(WebsiteData&&)>&&);
362 void deleteWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, WallTime modifiedSince, CompletionHandler<void()>&&);
363 void deleteWebsiteDataForOrigins(PAL::SessionID, OptionSet<WebsiteDataType>, const Vector<WebCore::SecurityOriginData>& origins, CompletionHandler<void()>&&);
364
365 void setMemoryCacheDisabled(bool);
366
367#if ENABLE(SERVICE_CONTROLS)
368 void setEnabledServices(bool hasImageServices, bool hasSelectionServices, bool hasRichContentServices);
369#endif
370
371 void handleInjectedBundleMessage(const String& messageName, const UserData& messageBody);
372 void setInjectedBundleParameter(const String& key, const IPC::DataReference&);
373 void setInjectedBundleParameters(const IPC::DataReference&);
374
375 enum class ShouldAcknowledgeWhenReadyToSuspend { No, Yes };
376 void actualPrepareToSuspend(ShouldAcknowledgeWhenReadyToSuspend);
377
378 bool hasPageRequiringPageCacheWhileSuspended() const;
379 bool areAllPagesSuspended() const;
380
381 void ensureAutomationSessionProxy(const String& sessionIdentifier);
382 void destroyAutomationSessionProxy();
383
384 void logDiagnosticMessageForNetworkProcessCrash();
385 bool hasVisibleWebPage() const;
386 void updateCPULimit();
387 enum class CPUMonitorUpdateReason { LimitHasChanged, VisibilityHasChanged };
388 void updateCPUMonitorState(CPUMonitorUpdateReason);
389
390 // AuxiliaryProcess
391 void initializeProcess(const AuxiliaryProcessInitializationParameters&) override;
392 void initializeProcessName(const AuxiliaryProcessInitializationParameters&) override;
393 void initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&) override;
394 void initializeConnection(IPC::Connection*) override;
395 bool shouldTerminate() override;
396 void terminate() override;
397
398#if USE(APPKIT)
399 void stopRunLoop() override;
400#endif
401
402#if ENABLE(MEDIA_STREAM)
403 void addMockMediaDevice(const WebCore::MockMediaDevice&);
404 void clearMockMediaDevices();
405 void removeMockMediaDevice(const String& persistentId);
406 void resetMockMediaDevices();
407#if ENABLE(SANDBOX_EXTENSIONS)
408 void grantUserMediaDeviceSandboxExtensions(MediaDeviceSandboxExtensions&&);
409 void revokeUserMediaDeviceSandboxExtensions(const Vector<String>&);
410#endif
411
412#endif
413
414 void platformInitializeProcess(const AuxiliaryProcessInitializationParameters&);
415
416 // IPC::Connection::Client
417 friend class WebConnectionToUIProcess;
418 void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
419 void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
420
421 // Implemented in generated WebProcessMessageReceiver.cpp
422 void didReceiveWebProcessMessage(IPC::Connection&, IPC::Decoder&);
423
424#if PLATFORM(MAC)
425 void setScreenProperties(const WebCore::ScreenProperties&);
426#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
427 void scrollerStylePreferenceChanged(bool useOverlayScrollbars);
428 void displayConfigurationChanged(CGDirectDisplayID, CGDisplayChangeSummaryFlags);
429 void displayWasRefreshed(CGDirectDisplayID);
430#endif
431#endif
432
433#if PLATFORM(COCOA)
434 void updateProcessName();
435#endif
436
437#if PLATFORM(IOS)
438 void backlightLevelDidChange(float backlightLevel);
439#endif
440
441#if PLATFORM(IOS_FAMILY)
442 void processTaskStateDidChange(ProcessTaskStateObserver::TaskState) final;
443 bool shouldFreezeOnSuspension() const;
444 void updateFreezerStatus();
445#endif
446
447#if ENABLE(VIDEO)
448 void suspendAllMediaBuffering();
449 void resumeAllMediaBuffering();
450#endif
451
452 void clearCurrentModifierStateForTesting();
453
454 RefPtr<WebConnectionToUIProcess> m_webConnection;
455
456 HashMap<uint64_t, RefPtr<WebPage>> m_pageMap;
457 HashMap<uint64_t, RefPtr<WebPageGroupProxy>> m_pageGroupMap;
458 RefPtr<InjectedBundle> m_injectedBundle;
459
460 Ref<EventDispatcher> m_eventDispatcher;
461#if PLATFORM(IOS_FAMILY)
462 RefPtr<ViewUpdateDispatcher> m_viewUpdateDispatcher;
463#endif
464 RefPtr<WebInspectorInterruptDispatcher> m_webInspectorInterruptDispatcher;
465
466 HashMap<PAL::SessionID, HashMap<unsigned, WallTime>> m_plugInAutoStartOriginHashes;
467 HashSet<String> m_plugInAutoStartOrigins;
468
469 bool m_hasSetCacheModel { false };
470 CacheModel m_cacheModel { CacheModel::DocumentViewer };
471
472#if PLATFORM(COCOA)
473 WTF::MachSendRight m_compositingRenderServerPort;
474#endif
475
476 bool m_fullKeyboardAccessEnabled { false };
477
478 HashMap<uint64_t, WebFrame*> m_frameMap;
479
480 typedef HashMap<const char*, std::unique_ptr<WebProcessSupplement>, PtrHash<const char*>> WebProcessSupplementMap;
481 WebProcessSupplementMap m_supplements;
482
483 TextCheckerState m_textCheckerState;
484
485 String m_uiProcessBundleIdentifier;
486 RefPtr<NetworkProcessConnection> m_networkProcessConnection;
487 WebLoaderStrategy& m_webLoaderStrategy;
488
489 Ref<WebCacheStorageProvider> m_cacheStorageProvider;
490
491 std::unique_ptr<LibWebRTCNetwork> m_libWebRTCNetwork;
492
493 HashSet<String> m_dnsPrefetchedHosts;
494 PAL::HysteresisActivity m_dnsPrefetchHystereris;
495
496 std::unique_ptr<WebAutomationSessionProxy> m_automationSessionProxy;
497
498#if ENABLE(NETSCAPE_PLUGIN_API)
499 RefPtr<PluginProcessConnectionManager> m_pluginProcessConnectionManager;
500#endif
501
502#if ENABLE(SERVICE_CONTROLS)
503 bool m_hasImageServices { false };
504 bool m_hasSelectionServices { false };
505 bool m_hasRichContentServices { false };
506#endif
507
508 bool m_processIsSuspended { false };
509
510 HashSet<uint64_t> m_pagesInWindows;
511 WebCore::Timer m_nonVisibleProcessCleanupTimer;
512
513 RefPtr<WebCore::ApplicationCacheStorage> m_applicationCacheStorage;
514
515#if PLATFORM(IOS_FAMILY)
516 WebSQLiteDatabaseTracker m_webSQLiteDatabaseTracker;
517 ProcessTaskStateObserver m_taskStateObserver { *this };
518#endif
519#if HAVE(VISIBILITY_PROPAGATION_VIEW)
520 std::unique_ptr<LayerHostingContext> m_contextForVisibilityPropagation;
521#endif
522
523 enum PageMarkingLayersAsVolatileCounterType { };
524 using PageMarkingLayersAsVolatileCounter = RefCounter<PageMarkingLayersAsVolatileCounterType>;
525 std::unique_ptr<PageMarkingLayersAsVolatileCounter> m_pageMarkingLayersAsVolatileCounter;
526 unsigned m_countOfPagesFailingToMarkVolatile { 0 };
527
528 bool m_suppressMemoryPressureHandler { false };
529#if PLATFORM(MAC)
530 std::unique_ptr<WebCore::CPUMonitor> m_cpuMonitor;
531 Optional<double> m_cpuLimit;
532
533 String m_uiProcessName;
534 WebCore::RegistrableDomain m_registrableDomain;
535#endif
536
537#if PLATFORM(COCOA)
538 enum class ProcessType { Inspector, ServiceWorker, PrewarmedWebContent, CachedWebContent, WebContent };
539 ProcessType m_processType { ProcessType::WebContent };
540#endif
541
542 HashMap<WebCore::UserGestureToken *, uint64_t> m_userGestureTokens;
543
544#if PLATFORM(WAYLAND)
545 std::unique_ptr<WaylandCompositorDisplay> m_waylandCompositorDisplay;
546#endif
547 bool m_hasSuspendedPageProxy { false };
548 bool m_isSuspending { false };
549
550#if ENABLE(MEDIA_STREAM) && ENABLE(SANDBOX_EXTENSIONS)
551 HashMap<String, RefPtr<SandboxExtension>> m_mediaCaptureSandboxExtensions;
552#endif
553
554#if PLATFORM(IOS)
555 float m_backlightLevel { 0 };
556#endif
557};
558
559} // namespace WebKit
560