5b0521894b2198ebcedebae63f6753565614b732
[WebKit.git] / Source / WebKit / UIProcess / WebProcessProxy.h
1 /*
2  * Copyright (C) 2010-2019 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 "APIUserInitiatedAction.h"
29 #include "AuxiliaryProcessProxy.h"
30 #include "BackgroundProcessResponsivenessTimer.h"
31 #include "MessageReceiverMap.h"
32 #include "PluginInfoStore.h"
33 #include "ProcessLauncher.h"
34 #include "ProcessTerminationReason.h"
35 #include "ProcessThrottler.h"
36 #include "ProcessThrottlerClient.h"
37 #include "ResponsivenessTimer.h"
38 #include "VisibleWebPageCounter.h"
39 #include "WebConnectionToWebProcess.h"
40 #include "WebPageProxyIdentifier.h"
41 #include "WebProcessProxyMessages.h"
42 #include <WebCore/FrameIdentifier.h>
43 #include <WebCore/PageIdentifier.h>
44 #include <WebCore/ProcessIdentifier.h>
45 #include <WebCore/RegistrableDomain.h>
46 #include <WebCore/SharedStringHash.h>
47 #include <memory>
48 #include <pal/SessionID.h>
49 #include <wtf/Forward.h>
50 #include <wtf/HashMap.h>
51 #include <wtf/HashSet.h>
52 #include <wtf/RefCounted.h>
53 #include <wtf/RefPtr.h>
54
55 namespace API {
56 class Navigation;
57 class PageConfiguration;
58 }
59
60 namespace WebCore {
61 class DeferrableOneShotTimer;
62 class ResourceRequest;
63 struct PluginInfo;
64 struct SecurityOriginData;
65 }
66
67 namespace WebKit {
68
69 class NetworkProcessProxy;
70 class ObjCObjectGraph;
71 class PageClient;
72 class ProvisionalPageProxy;
73 class UserMediaCaptureManagerProxy;
74 class VisitedLinkStore;
75 class WebBackForwardListItem;
76 class WebFrameProxy;
77 class WebPageGroup;
78 class WebPageProxy;
79 class WebProcessPool;
80 class WebUserContentControllerProxy;
81 class WebsiteDataStore;
82 enum class WebsiteDataType;
83 struct WebNavigationDataStore;
84 struct WebPageCreationParameters;
85 struct WebPreferencesStore;
86 struct WebsiteData;
87
88 #if PLATFORM(IOS_FAMILY)
89 enum ForegroundWebProcessCounterType { };
90 typedef RefCounter<ForegroundWebProcessCounterType> ForegroundWebProcessCounter;
91 typedef ForegroundWebProcessCounter::Token ForegroundWebProcessToken;
92 enum BackgroundWebProcessCounterType { };
93 typedef RefCounter<BackgroundWebProcessCounterType> BackgroundWebProcessCounter;
94 typedef BackgroundWebProcessCounter::Token BackgroundWebProcessToken;
95 #endif
96
97 enum class AllowProcessCaching { No, Yes };
98
99 class WebProcessProxy : public AuxiliaryProcessProxy, public ResponsivenessTimer::Client, public ThreadSafeRefCounted<WebProcessProxy>, public CanMakeWeakPtr<WebProcessProxy>, private ProcessThrottlerClient {
100 public:
101     typedef HashMap<WebCore::FrameIdentifier, RefPtr<WebFrameProxy>> WebFrameProxyMap;
102     typedef HashMap<WebPageProxyIdentifier, WebPageProxy*> WebPageProxyMap;
103     typedef HashMap<uint64_t, RefPtr<API::UserInitiatedAction>> UserInitiatedActionMap;
104
105     enum class IsPrewarmed {
106         No,
107         Yes
108     };
109
110     enum class ShouldLaunchProcess : bool { No, Yes };
111
112     static Ref<WebProcessProxy> create(WebProcessPool&, WebsiteDataStore*, IsPrewarmed, ShouldLaunchProcess = ShouldLaunchProcess::Yes);
113     static Ref<WebProcessProxy> createForServiceWorkers(WebProcessPool&, WebCore::RegistrableDomain&&, WebsiteDataStore&);
114
115     ~WebProcessProxy();
116
117     static void forWebPagesWithOrigin(PAL::SessionID, const WebCore::SecurityOriginData&, const Function<void(WebPageProxy&)>&);
118
119     WebConnection* webConnection() const { return m_webConnection.get(); }
120
121     unsigned suspendedPageCount() const { return m_suspendedPageCount; }
122     void incrementSuspendedPageCount();
123     void decrementSuspendedPageCount();
124
125     WebProcessPool* processPoolIfExists() const;
126     WebProcessPool& processPool() const;
127
128     WebCore::RegistrableDomain registrableDomain() const { return m_registrableDomain.valueOr(WebCore::RegistrableDomain { }); }
129     void setIsInProcessCache(bool);
130     bool isInProcessCache() const { return m_isInProcessCache; }
131
132     WebsiteDataStore& websiteDataStore() const { ASSERT(m_websiteDataStore); return *m_websiteDataStore; }
133     void setWebsiteDataStore(WebsiteDataStore&);
134     
135     PAL::SessionID sessionID() const;
136
137     static WebProcessProxy* processForIdentifier(WebCore::ProcessIdentifier);
138     static WebPageProxy* webPage(WebPageProxyIdentifier);
139     Ref<WebPageProxy> createWebPage(PageClient&, Ref<API::PageConfiguration>&&);
140
141     enum class BeginsUsingDataStore : bool { No, Yes };
142     void addExistingWebPage(WebPageProxy&, BeginsUsingDataStore);
143
144     enum class EndsUsingDataStore : bool { No, Yes };
145     void removeWebPage(WebPageProxy&, EndsUsingDataStore);
146
147     void addProvisionalPageProxy(ProvisionalPageProxy&);
148     void removeProvisionalPageProxy(ProvisionalPageProxy&);
149     
150     typename WebPageProxyMap::ValuesConstIteratorRange pages() const { return m_pageMap.values(); }
151     unsigned pageCount() const { return m_pageMap.size(); }
152     unsigned provisionalPageCount() const { return m_provisionalPages.size(); }
153     unsigned visiblePageCount() const { return m_visiblePageCounter.value(); }
154
155     void activePagesDomainsForTesting(CompletionHandler<void(Vector<String>&&)>&&); // This is what is reported to ActivityMonitor.
156
157     bool isRunningServiceWorkers() const { return !!m_serviceWorkerInformation; }
158
159     void didCreateWebPageInProcess(WebCore::PageIdentifier);
160
161     void addVisitedLinkStoreUser(VisitedLinkStore&, WebPageProxyIdentifier);
162     void removeVisitedLinkStoreUser(VisitedLinkStore&, WebPageProxyIdentifier);
163
164     void addWebUserContentControllerProxy(WebUserContentControllerProxy&, WebPageCreationParameters&);
165     void didDestroyWebUserContentControllerProxy(WebUserContentControllerProxy&);
166
167     RefPtr<API::UserInitiatedAction> userInitiatedActivity(uint64_t);
168
169     ResponsivenessTimer& responsivenessTimer() { return m_responsivenessTimer; }
170     bool isResponsive() const;
171
172     WebFrameProxy* webFrame(WebCore::FrameIdentifier) const;
173     bool canCreateFrame(WebCore::FrameIdentifier) const;
174     void frameCreated(WebCore::FrameIdentifier, WebFrameProxy&);
175     void disconnectFramesFromPage(WebPageProxy*); // Including main frame.
176     size_t frameCountInPage(WebPageProxy*) const; // Including main frame.
177
178     VisibleWebPageToken visiblePageToken() const;
179
180     void updateTextCheckerState();
181
182     void willAcquireUniversalFileReadSandboxExtension() { m_mayHaveUniversalFileReadSandboxExtension = true; }
183     void assumeReadAccessToBaseURL(WebPageProxy&, const String&);
184     bool hasAssumedReadAccessToURL(const URL&) const;
185
186     bool checkURLReceivedFromWebProcess(const String&);
187     bool checkURLReceivedFromWebProcess(const URL&);
188
189     static bool fullKeyboardAccessEnabled();
190
191     void didSaveToPageCache();
192     void releasePageCache();
193
194     void fetchWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, CompletionHandler<void(WebsiteData)>&&);
195     void deleteWebsiteData(PAL::SessionID, OptionSet<WebsiteDataType>, WallTime modifiedSince, CompletionHandler<void()>&&);
196     void deleteWebsiteDataForOrigins(PAL::SessionID, OptionSet<WebsiteDataType>, const Vector<WebCore::SecurityOriginData>&, CompletionHandler<void()>&&);
197
198 #if ENABLE(RESOURCE_LOAD_STATISTICS)
199     static void notifyPageStatisticsAndDataRecordsProcessed();
200     static void notifyPageStatisticsTelemetryFinished(API::Object* messageBody);
201
202     static void notifyWebsiteDataDeletionForRegistrableDomainsFinished();
203     static void notifyWebsiteDataScanForRegistrableDomainsFinished();
204 #endif
205
206     void enableSuddenTermination();
207     void disableSuddenTermination();
208     bool isSuddenTerminationEnabled() { return !m_numberOfTimesSuddenTerminationWasDisabled; }
209
210     void requestTermination(ProcessTerminationReason);
211
212     void stopResponsivenessTimer();
213
214     RefPtr<API::Object> transformHandlesToObjects(API::Object*);
215     static RefPtr<API::Object> transformObjectsToHandles(API::Object*);
216
217 #if PLATFORM(COCOA)
218     RefPtr<ObjCObjectGraph> transformHandlesToObjects(ObjCObjectGraph&);
219     static RefPtr<ObjCObjectGraph> transformObjectsToHandles(ObjCObjectGraph&);
220 #endif
221
222     void windowServerConnectionStateChanged();
223
224     void processReadyToSuspend();
225     void didCancelProcessSuspension();
226
227     void setIsHoldingLockedFiles(bool);
228
229     ProcessThrottler& throttler() { return m_throttler; }
230
231     void isResponsive(CompletionHandler<void(bool isWebProcessResponsive)>&&);
232     void isResponsiveWithLazyStop();
233     void didReceiveMainThreadPing();
234     void didReceiveBackgroundResponsivenessPing();
235
236     void memoryPressureStatusChanged(bool isUnderMemoryPressure) { m_isUnderMemoryPressure = isUnderMemoryPressure; }
237     bool isUnderMemoryPressure() const { return m_isUnderMemoryPressure; }
238     void didExceedInactiveMemoryLimitWhileActive();
239
240     void processTerminated();
241
242     void didExceedCPULimit();
243     void didExceedActiveMemoryLimit();
244     void didExceedInactiveMemoryLimit();
245
246     void didCommitProvisionalLoad() { m_hasCommittedAnyProvisionalLoads = true; }
247     bool hasCommittedAnyProvisionalLoads() const { return m_hasCommittedAnyProvisionalLoads; }
248
249 #if PLATFORM(WATCHOS)
250     void takeBackgroundActivityTokenForFullscreenInput();
251     void releaseBackgroundActivityTokenForFullscreenInput();
252 #endif
253
254     bool isPrewarmed() const { return m_isPrewarmed; }
255     void markIsNoLongerInPrewarmedPool();
256
257 #if PLATFORM(COCOA)
258     Vector<String> mediaMIMETypes() const;
259     void cacheMediaMIMETypes(const Vector<String>&);
260 #endif
261
262 #if PLATFORM(MAC)
263     void requestHighPerformanceGPU();
264     void releaseHighPerformanceGPU();
265 #endif
266
267 #if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
268     void startDisplayLink(unsigned observerID, uint32_t displayID);
269     void stopDisplayLink(unsigned observerID, uint32_t displayID);
270 #endif
271
272     // Called when the web process has crashed or we know that it will terminate soon.
273     // Will potentially cause the WebProcessProxy object to be freed.
274     void shutDown();
275     void maybeShutDown(AllowProcessCaching = AllowProcessCaching::Yes);
276
277     void didStartProvisionalLoadForMainFrame(const URL&);
278
279     // ProcessThrottlerClient
280     void sendProcessWillSuspendImminently() override;
281     void sendPrepareToSuspend() override;
282     void sendCancelPrepareToSuspend() override;
283     void sendProcessDidResume() override;
284     void didSetAssertionState(AssertionState) override;
285
286 #if PLATFORM(COCOA)
287     enum SandboxExtensionType : uint32_t {
288         None = 0,
289         Video = 1 << 0,
290         Audio = 1 << 1
291     };
292
293     typedef uint32_t MediaCaptureSandboxExtensions;
294
295     bool hasVideoCaptureExtension() const { return m_mediaCaptureSandboxExtensions & Video; }
296     void grantVideoCaptureExtension() { m_mediaCaptureSandboxExtensions |= Video; }
297     void revokeVideoCaptureExtension() { m_mediaCaptureSandboxExtensions &= ~Video; }
298
299     bool hasAudioCaptureExtension() const { return m_mediaCaptureSandboxExtensions & Audio; }
300     void grantAudioCaptureExtension() { m_mediaCaptureSandboxExtensions |= Audio; }
301     void revokeAudioCaptureExtension() { m_mediaCaptureSandboxExtensions &= ~Audio; }
302 #endif
303
304 #if PLATFORM(IOS_FAMILY)
305     void unblockAccessibilityServerIfNeeded();
306 #endif
307
308 #if PLATFORM(IOS_FAMILY)
309     void processWasUnexpectedlyUnsuspended();
310 #endif
311
312     void webPageMediaStateDidChange(WebPageProxy&);
313
314     void ref() final { ThreadSafeRefCounted::ref(); }
315     void deref() final { ThreadSafeRefCounted::deref(); }
316
317 #if ENABLE(SERVICE_WORKER)
318     void establishServiceWorkerContext(const WebPreferencesStore&);
319     void setServiceWorkerUserAgent(const String&);
320     void updateServiceWorkerPreferencesStore(const WebPreferencesStore&);
321     bool hasServiceWorkerPageProxy(WebPageProxyIdentifier pageProxyID) { return m_serviceWorkerInformation && m_serviceWorkerInformation->serviceWorkerPageProxyID == pageProxyID; }
322 #endif
323
324 protected:
325     WebProcessProxy(WebProcessPool&, WebsiteDataStore*, IsPrewarmed);
326
327     // AuxiliaryProcessProxy
328     void getLaunchOptions(ProcessLauncher::LaunchOptions&) override;
329     void platformGetLaunchOptions(ProcessLauncher::LaunchOptions&) override;
330     void connectionWillOpen(IPC::Connection&) override;
331     void processWillShutDown(IPC::Connection&) override;
332     bool shouldSendPendingMessage(const PendingMessage&) final;
333     
334     // ProcessLauncher::Client
335     void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
336
337 #if PLATFORM(COCOA)
338     void cacheMediaMIMETypesInternal(const Vector<String>&);
339 #endif
340
341     bool shouldConfigureJSCForTesting() const final;
342     bool isJITEnabled() const final;
343
344     void validateFreezerStatus();
345
346 private:
347     // IPC message handlers.
348     void updateBackForwardItem(const BackForwardListItemState&);
349     void didDestroyFrame(WebCore::FrameIdentifier);
350     void didDestroyUserGestureToken(uint64_t);
351
352     bool canBeAddedToWebProcessCache() const;
353     void shouldTerminate(CompletionHandler<void(bool)>&&);
354
355     bool hasProvisionalPageWithID(WebPageProxyIdentifier) const;
356     bool isAllowedToUpdateBackForwardItem(WebBackForwardListItem&) const;
357
358     // Plugins
359 #if ENABLE(NETSCAPE_PLUGIN_API)
360     void getPlugins(bool refresh, CompletionHandler<void(Vector<WebCore::PluginInfo>&& plugins, Vector<WebCore::PluginInfo>&& applicationPlugins, Optional<Vector<WebCore::SupportedPluginIdentifier>>&&)>&&);
361 #endif // ENABLE(NETSCAPE_PLUGIN_API)
362 #if ENABLE(NETSCAPE_PLUGIN_API)
363     void getPluginProcessConnection(uint64_t pluginProcessToken, Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply&&);
364 #endif
365     void addPlugInAutoStartOriginHash(String&& pageOrigin, uint32_t hash);
366     void plugInDidReceiveUserInteraction(uint32_t hash);
367     
368     void getNetworkProcessConnection(Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply&&);
369
370     bool platformIsBeingDebugged() const;
371     bool shouldAllowNonValidInjectedCode() const;
372
373     static const HashSet<String>& platformPathsWithAssumedReadAccess();
374
375     void updateBackgroundResponsivenessTimer();
376
377     void processDidTerminateOrFailedToLaunch();
378
379     bool isReleaseLoggingAllowed() const;
380
381     // IPC::Connection::Client
382     friend class WebConnectionToWebProcess;
383     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
384     void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
385     void didClose(IPC::Connection&) override;
386     void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override;
387
388     // ResponsivenessTimer::Client
389     void didBecomeUnresponsive() override;
390     void didBecomeResponsive() override;
391     void willChangeIsResponsive() override;
392     void didChangeIsResponsive() override;
393     bool mayBecomeUnresponsive() override;
394
395     // Implemented in generated WebProcessProxyMessageReceiver.cpp
396     void didReceiveWebProcessProxyMessage(IPC::Connection&, IPC::Decoder&);
397     void didReceiveSyncWebProcessProxyMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&);
398
399     bool canTerminateAuxiliaryProcess();
400
401     void didCollectPrewarmInformation(const WebCore::RegistrableDomain&, const WebCore::PrewarmInformation&);
402
403     void logDiagnosticMessageForResourceLimitTermination(const String& limitKey);
404     
405     void updateRegistrationWithDataStore();
406
407     enum class IsWeak { No, Yes };
408     template<typename T> class WeakOrStrongPtr {
409     public:
410         WeakOrStrongPtr(T& object, IsWeak isWeak)
411             : m_isWeak(isWeak)
412             , m_weakObject(makeWeakPtr(object))
413         {
414             updateStrongReference();
415         }
416
417         void setIsWeak(IsWeak isWeak)
418         {
419             m_isWeak = isWeak;
420             updateStrongReference();
421         }
422
423         T* get() const { return m_weakObject.get(); }
424         T* operator->() const { return m_weakObject.get(); }
425         T& operator*() const { return *m_weakObject; }
426         explicit operator bool() const { return !!m_weakObject; }
427
428     private:
429         void updateStrongReference()
430         {
431             m_strongObject = m_isWeak == IsWeak::Yes ? nullptr : m_weakObject.get();
432         }
433
434         IsWeak m_isWeak;
435         WeakPtr<T> m_weakObject;
436         RefPtr<T> m_strongObject;
437     };
438
439     ResponsivenessTimer m_responsivenessTimer;
440     BackgroundProcessResponsivenessTimer m_backgroundResponsivenessTimer;
441     
442     RefPtr<WebConnectionToWebProcess> m_webConnection;
443     WeakOrStrongPtr<WebProcessPool> m_processPool; // Pre-warmed and cached processes do not hold a strong reference to their pool.
444
445     bool m_mayHaveUniversalFileReadSandboxExtension; // True if a read extension for "/" was ever granted - we don't track whether WebProcess still has it.
446     HashSet<String> m_localPathsWithAssumedReadAccess;
447
448     WebPageProxyMap m_pageMap;
449     WebFrameProxyMap m_frameMap;
450     HashSet<ProvisionalPageProxy*> m_provisionalPages;
451     UserInitiatedActionMap m_userInitiatedActionMap;
452
453     HashMap<VisitedLinkStore*, HashSet<WebPageProxyIdentifier>> m_visitedLinkStoresWithUsers;
454     HashSet<WebUserContentControllerProxy*> m_webUserContentControllerProxies;
455
456     int m_numberOfTimesSuddenTerminationWasDisabled;
457     ProcessThrottler m_throttler;
458     ProcessThrottler::BackgroundActivityToken m_tokenForHoldingLockedFiles;
459 #if PLATFORM(IOS_FAMILY)
460     ForegroundWebProcessToken m_foregroundToken;
461     BackgroundWebProcessToken m_backgroundToken;
462     bool m_hasSentMessageToUnblockAccessibilityServer { false };
463     std::unique_ptr<WebCore::DeferrableOneShotTimer> m_unexpectedActivityTimer;
464 #endif
465
466     HashMap<String, uint64_t> m_pageURLRetainCountMap;
467
468     Optional<WebCore::RegistrableDomain> m_registrableDomain;
469     bool m_isInProcessCache { false };
470
471     enum class NoOrMaybe { No, Maybe } m_isResponsive;
472     Vector<CompletionHandler<void(bool webProcessIsResponsive)>> m_isResponsiveCallbacks;
473
474     VisibleWebPageCounter m_visiblePageCounter;
475
476     RefPtr<WebsiteDataStore> m_websiteDataStore;
477
478     bool m_isUnderMemoryPressure { false };
479
480 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
481     std::unique_ptr<UserMediaCaptureManagerProxy> m_userMediaCaptureManagerProxy;
482 #endif
483
484     unsigned m_suspendedPageCount { 0 };
485     bool m_hasCommittedAnyProvisionalLoads { false };
486     bool m_isPrewarmed;
487     bool m_hasAudibleWebPage { false };
488
489 #if PLATFORM(WATCHOS)
490     ProcessThrottler::BackgroundActivityToken m_backgroundActivityTokenForFullscreenFormControls;
491 #endif
492
493 #if PLATFORM(COCOA)
494     MediaCaptureSandboxExtensions m_mediaCaptureSandboxExtensions { SandboxExtensionType::None };
495 #endif
496
497     struct ServiceWorkerInformation {
498         WebPageProxyIdentifier serviceWorkerPageProxyID;
499         WebCore::PageIdentifier serviceWorkerPageID;
500     };
501     Optional<ServiceWorkerInformation> m_serviceWorkerInformation;
502 };
503
504 } // namespace WebKit