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