52b25759201750b477ff9497e483efd63f306d45
[WebKit-https.git] / Source / WebKit2 / UIProcess / WebContext.h
1 /*
2  * Copyright (C) 2010, 2011, 2012, 2013 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 #ifndef WebContext_h
27 #define WebContext_h
28
29 #include "APIObject.h"
30 #include "DownloadProxyMap.h"
31 #include "GenericCallback.h"
32 #include "ImmutableDictionary.h"
33 #include "MessageReceiver.h"
34 #include "MessageReceiverMap.h"
35 #include "PlugInAutoStartProvider.h"
36 #include "PluginInfoStore.h"
37 #include "ProcessModel.h"
38 #include "StatisticsRequest.h"
39 #include "StorageManager.h"
40 #include "VisitedLinkProvider.h"
41 #include "WebContextClient.h"
42 #include "WebContextConnectionClient.h"
43 #include "WebContextInjectedBundleClient.h"
44 #include "WebProcessProxy.h"
45 #include <WebCore/LinkHash.h>
46 #include <WebCore/SessionID.h>
47 #include <wtf/Forward.h>
48 #include <wtf/HashMap.h>
49 #include <wtf/HashSet.h>
50 #include <wtf/PassRefPtr.h>
51 #include <wtf/RefPtr.h>
52 #include <wtf/text/StringHash.h>
53 #include <wtf/text/WTFString.h>
54
55 #if ENABLE(DATABASE_PROCESS)
56 #include "DatabaseProcessProxy.h"
57 #endif
58
59 #if ENABLE(NETWORK_PROCESS)
60 #include "NetworkProcessProxy.h"
61 #endif
62
63 #if PLATFORM(COCOA)
64 OBJC_CLASS NSMutableDictionary;
65 OBJC_CLASS NSObject;
66 OBJC_CLASS NSString;
67 #endif
68
69 namespace API {
70 class DownloadClient;
71 class HistoryClient;
72 }
73
74 namespace WebKit {
75
76 class DownloadProxy;
77 class WebContextSupplement;
78 class WebIconDatabase;
79 class WebPageGroup;
80 class WebPageProxy;
81 struct StatisticsData;
82 struct WebPageConfiguration;
83 struct WebProcessCreationParameters;
84     
85 typedef GenericCallback<ImmutableDictionary*> DictionaryCallback;
86
87 #if ENABLE(NETWORK_PROCESS)
88 struct NetworkProcessCreationParameters;
89 #endif
90
91 #if PLATFORM(COCOA)
92 int networkProcessLatencyQOS();
93 int networkProcessThroughputQOS();
94 int webProcessLatencyQOS();
95 int webProcessThroughputQOS();
96 #endif
97
98 class WebContext : public API::ObjectImpl<API::Object::Type::Context>, private IPC::MessageReceiver
99 #if ENABLE(NETSCAPE_PLUGIN_API)
100     , private PluginInfoStoreClient
101 #endif
102     {
103 public:
104     WebContext(const String& injectedBundlePath);
105
106     static PassRefPtr<WebContext> create(const String& injectedBundlePath);
107     virtual ~WebContext();
108
109     static const Vector<WebContext*>& allContexts();
110
111     template <typename T>
112     T* supplement()
113     {
114         return static_cast<T*>(m_supplements.get(T::supplementName()));
115     }
116
117     template <typename T>
118     void addSupplement()
119     {
120         m_supplements.add(T::supplementName(), T::create(this));
121     }
122
123     void addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver&);
124     void addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver&);
125     void removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID);
126
127     bool dispatchMessage(IPC::Connection*, IPC::MessageDecoder&);
128     bool dispatchSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&);
129
130     void initializeClient(const WKContextClientBase*);
131     void initializeInjectedBundleClient(const WKContextInjectedBundleClientBase*);
132     void initializeConnectionClient(const WKContextConnectionClientBase*);
133     void setHistoryClient(std::unique_ptr<API::HistoryClient>);
134     void setDownloadClient(std::unique_ptr<API::DownloadClient>);
135
136     void setProcessModel(ProcessModel); // Can only be called when there are no processes running.
137     ProcessModel processModel() const { return m_processModel; }
138
139     void setMaximumNumberOfProcesses(unsigned); // Can only be called when there are no processes running.
140     unsigned maximumNumberOfProcesses() const { return m_webProcessCountLimit; }
141
142     // WebProcess or NetworkProcess as approporiate for current process model. The connection must be non-null.
143     IPC::Connection* networkingProcessConnection();
144
145     template<typename T> void sendToAllProcesses(const T& message);
146     template<typename T> void sendToAllProcessesRelaunchingThemIfNecessary(const T& message);
147     template<typename T> void sendToOneProcess(T&& message);
148
149     // Sends the message to WebProcess or NetworkProcess as approporiate for current process model.
150     template<typename T> void sendToNetworkingProcess(T&& message);
151     template<typename T> void sendToNetworkingProcessRelaunchingIfNecessary(T&& message);
152
153     void processWillOpenConnection(WebProcessProxy*);
154     void processWillCloseConnection(WebProcessProxy*);
155     void processDidFinishLaunching(WebProcessProxy*);
156
157     // Disconnect the process from the context.
158     void disconnectProcess(WebProcessProxy*);
159
160     StorageManager& storageManager() const { return *m_storageManager; }
161
162     PassRefPtr<WebPageProxy> createWebPage(PageClient&, WebPageConfiguration);
163
164     const String& injectedBundlePath() const { return m_injectedBundlePath; }
165
166     DownloadProxy* download(WebPageProxy* initiatingPage, const WebCore::ResourceRequest&);
167
168     void setInjectedBundleInitializationUserData(PassRefPtr<API::Object> userData) { m_injectedBundleInitializationUserData = userData; }
169
170     void postMessageToInjectedBundle(const String&, API::Object*);
171
172     // InjectedBundle client
173     void didReceiveMessageFromInjectedBundle(const String&, API::Object*);
174     void didReceiveSynchronousMessageFromInjectedBundle(const String&, API::Object*, RefPtr<API::Object>& returnData);
175
176     void populateVisitedLinks();
177
178 #if ENABLE(NETSCAPE_PLUGIN_API)
179     void setAdditionalPluginsDirectory(const String&);
180
181     PluginInfoStore& pluginInfoStore() { return m_pluginInfoStore; }
182 #endif
183
184     void setAlwaysUsesComplexTextCodePath(bool);
185     void setShouldUseFontSmoothing(bool);
186     
187     void registerURLSchemeAsEmptyDocument(const String&);
188     void registerURLSchemeAsSecure(const String&);
189     void setDomainRelaxationForbiddenForURLScheme(const String&);
190     void registerURLSchemeAsLocal(const String&);
191     void registerURLSchemeAsNoAccess(const String&);
192     void registerURLSchemeAsDisplayIsolated(const String&);
193     void registerURLSchemeAsCORSEnabled(const String&);
194 #if ENABLE(CACHE_PARTITIONING)
195     void registerURLSchemeAsCachePartitioned(const String&);
196 #endif
197
198     VisitedLinkProvider& visitedLinkProvider() { return *m_visitedLinkProvider; }
199
200     // MessageReceiver.
201     virtual void didReceiveMessage(IPC::Connection*, IPC::MessageDecoder&) override;
202     virtual void didReceiveSyncMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override;
203
204     void setCacheModel(CacheModel);
205     CacheModel cacheModel() const { return m_cacheModel; }
206
207     void setDefaultRequestTimeoutInterval(double);
208
209     void startMemorySampler(const double interval);
210     void stopMemorySampler();
211
212 #if USE(SOUP)
213     void setInitialHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) { m_initialHTTPCookieAcceptPolicy = policy; }
214 #endif
215     void setEnhancedAccessibility(bool);
216     
217     // Downloads.
218     DownloadProxy* createDownloadProxy();
219     API::DownloadClient& downloadClient() { return *m_downloadClient; }
220
221     API::HistoryClient& historyClient() { return *m_historyClient; }
222     WebContextClient& client() { return m_client; }
223
224     WebIconDatabase* iconDatabase() const { return m_iconDatabase.get(); }
225 #if ENABLE(NETSCAPE_PLUGIN_API)
226     WebPluginSiteDataManager* pluginSiteDataManager() const { return m_pluginSiteDataManager.get(); }
227 #endif
228
229     struct Statistics {
230         unsigned wkViewCount;
231         unsigned wkPageCount;
232         unsigned wkFrameCount;
233     };
234     static Statistics& statistics();    
235
236     void setApplicationCacheDirectory(const String& dir) { m_overrideApplicationCacheDirectory = dir; }
237     void setDatabaseDirectory(const String& dir) { m_overrideDatabaseDirectory = dir; }
238     void setIconDatabasePath(const String&);
239     String iconDatabasePath() const;
240     void setLocalStorageDirectory(const String&);
241     void setDiskCacheDirectory(const String& dir) { m_overrideDiskCacheDirectory = dir; }
242     void setCookieStorageDirectory(const String& dir) { m_overrideCookieStorageDirectory = dir; }
243
244     void useTestingNetworkSession();
245
246     void allowSpecificHTTPSCertificateForHost(const WebCertificateInfo*, const String& host);
247
248     WebProcessProxy& ensureSharedWebProcess();
249     WebProcessProxy& createNewWebProcessRespectingProcessCountLimit(); // Will return an existing one if limit is met.
250     void warmInitialProcess();
251
252     bool shouldTerminate(WebProcessProxy*);
253
254     void disableProcessTermination() { m_processTerminationEnabled = false; }
255     void enableProcessTermination();
256
257     // Defaults to false.
258     void setHTTPPipeliningEnabled(bool);
259     bool httpPipeliningEnabled() const;
260
261     void getStatistics(uint32_t statisticsMask, PassRefPtr<DictionaryCallback>);
262     
263     void garbageCollectJavaScriptObjects();
264     void setJavaScriptGarbageCollectorTimerEnabled(bool flag);
265
266 #if PLATFORM(COCOA)
267     static bool omitPDFSupport();
268 #endif
269
270     void fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled);
271
272     void textCheckerStateChanged();
273
274     PassRefPtr<ImmutableDictionary> plugInAutoStartOriginHashes() const;
275     void setPlugInAutoStartOriginHashes(ImmutableDictionary&);
276     void setPlugInAutoStartOrigins(API::Array&);
277     void setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(ImmutableDictionary&, double time);
278
279     // Network Process Management
280
281     void setUsesNetworkProcess(bool);
282     bool usesNetworkProcess() const;
283
284 #if ENABLE(NETWORK_PROCESS)
285     void ensureNetworkProcess();
286     NetworkProcessProxy* networkProcess() { return m_networkProcess.get(); }
287     void networkProcessCrashed(NetworkProcessProxy*);
288
289     void getNetworkProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetNetworkProcessConnection::DelayedReply>);
290 #endif
291
292 #if ENABLE(DATABASE_PROCESS)
293     void ensureDatabaseProcess();
294     void getDatabaseProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetDatabaseProcessConnection::DelayedReply>);
295 #endif
296
297 #if PLATFORM(COCOA)
298     bool processSuppressionEnabled() const;
299     static bool processSuppressionIsEnabledForAllContexts();
300     static bool processSuppressionPreferenceIsEnabledForAllContexts();
301 #endif
302
303     void windowServerConnectionStateChanged();
304
305     static void willStartUsingPrivateBrowsing();
306     static void willStopUsingPrivateBrowsing();
307
308     static bool isEphemeralSession(WebCore::SessionID);
309
310 #if USE(SOUP)
311     void setIgnoreTLSErrors(bool);
312     bool ignoreTLSErrors() const { return m_ignoreTLSErrors; }
313 #endif
314
315     static void setInvalidMessageCallback(void (*)(WKStringRef));
316     static void didReceiveInvalidMessage(const IPC::StringReference& messageReceiverName, const IPC::StringReference& messageName);
317
318     void processDidCachePage(WebProcessProxy*);
319
320     bool isURLKnownHSTSHost(const String& urlString, bool privateBrowsingEnabled) const;
321     void resetHSTSHosts();
322
323 #if ENABLE(CUSTOM_PROTOCOLS)
324     void registerSchemeForCustomProtocol(const String&);
325     void unregisterSchemeForCustomProtocol(const String&);
326
327     static HashSet<String>& globalURLSchemesWithCustomProtocolHandlers();
328     static void registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&);
329     static void unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&);
330 #endif
331
332 #if PLATFORM(COCOA)
333     void updateProcessSuppressionState() const;
334
335     NSMutableDictionary *ensureBundleParameters();
336     NSMutableDictionary *bundleParameters() { return m_bundleParameters.get(); }
337 #endif
338
339     void setMemoryCacheDisabled(bool);
340
341 private:
342     void platformInitialize();
343
344     void platformInitializeWebProcess(WebProcessCreationParameters&);
345     void platformInvalidateContext();
346
347     WebProcessProxy& createNewWebProcess();
348
349     void requestWebContentStatistics(StatisticsRequest*);
350     void requestNetworkingStatistics(StatisticsRequest*);
351
352 #if ENABLE(NETWORK_PROCESS)
353     void platformInitializeNetworkProcess(NetworkProcessCreationParameters&);
354 #endif
355
356 #if PLATFORM(IOS)
357     void writeWebContentToPasteboard(const WebCore::PasteboardWebContent&);
358     void writeImageToPasteboard(const WebCore::PasteboardImage&);
359     void writeStringToPasteboard(const String& pasteboardType, const String&);
360     void readStringFromPasteboard(uint64_t index, const String& pasteboardType, WTF::String&);
361     void readURLFromPasteboard(uint64_t index, const String& pasteboardType, String&);
362     void readBufferFromPasteboard(uint64_t index, const String& pasteboardType, SharedMemory::Handle&, uint64_t& size);
363     void getPasteboardItemsCount(uint64_t& itemsCount);
364 #endif
365 #if PLATFORM(COCOA)
366     void getPasteboardTypes(const String& pasteboardName, Vector<String>& pasteboardTypes);
367     void getPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames);
368     void getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, String&);
369     void getPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, SharedMemory::Handle&, uint64_t& size);
370     void pasteboardCopy(const String& fromPasteboard, const String& toPasteboard, uint64_t& newChangeCount);
371     void getPasteboardChangeCount(const String& pasteboardName, uint64_t& changeCount);
372     void getPasteboardUniqueName(String& pasteboardName);
373     void getPasteboardColor(const String& pasteboardName, WebCore::Color&);
374     void getPasteboardURL(const String& pasteboardName, WTF::String&);
375     void addPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount);
376     void setPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes, uint64_t& newChangeCount);
377     void setPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, const Vector<String>& pathnames, uint64_t& newChangeCount);
378     void setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String&, uint64_t& newChangeCount);
379     void setPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, const SharedMemory::Handle&, uint64_t size, uint64_t& newChangeCount);
380 #endif
381
382 #if !PLATFORM(COCOA)
383     // FIXME: This a dummy message, to avoid breaking the build for platforms that don't require
384     // any synchronous messages, and should be removed when <rdar://problem/8775115> is fixed.
385     void dummy(bool&);
386 #endif
387
388     void didGetStatistics(const StatisticsData&, uint64_t callbackID);
389         
390     // Implemented in generated WebContextMessageReceiver.cpp
391     void didReceiveWebContextMessage(IPC::Connection*, IPC::MessageDecoder&);
392     void didReceiveSyncWebContextMessage(IPC::Connection*, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&);
393
394     static void languageChanged(void* context);
395     void languageChanged();
396
397     String applicationCacheDirectory() const;
398     String platformDefaultApplicationCacheDirectory() const;
399
400     String databaseDirectory() const;
401     String platformDefaultDatabaseDirectory() const;
402
403     String platformDefaultIconDatabasePath() const;
404
405     String localStorageDirectory() const;
406     String platformDefaultLocalStorageDirectory() const;
407
408     String diskCacheDirectory() const;
409     String platformDefaultDiskCacheDirectory() const;
410
411     String cookieStorageDirectory() const;
412     String platformDefaultCookieStorageDirectory() const;
413
414 #if PLATFORM(COCOA)
415     void registerNotificationObservers();
416     void unregisterNotificationObservers();
417 #endif
418
419     void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash);
420     void plugInDidReceiveUserInteraction(unsigned plugInOriginHash);
421
422     void setAnyPageGroupMightHavePrivateBrowsingEnabled(bool);
423
424 #if ENABLE(NETSCAPE_PLUGIN_API)
425     // PluginInfoStoreClient:
426     virtual void pluginInfoStoreDidLoadPlugins(PluginInfoStore*) override;
427 #endif
428
429     IPC::MessageReceiverMap m_messageReceiverMap;
430
431     ProcessModel m_processModel;
432     unsigned m_webProcessCountLimit; // The limit has no effect when process model is ProcessModelSharedSecondaryProcess.
433     
434     Vector<RefPtr<WebProcessProxy>> m_processes;
435     bool m_haveInitialEmptyProcess;
436
437     WebProcessProxy* m_processWithPageCache;
438
439     Ref<WebPageGroup> m_defaultPageGroup;
440
441     RefPtr<API::Object> m_injectedBundleInitializationUserData;
442     String m_injectedBundlePath;
443     WebContextInjectedBundleClient m_injectedBundleClient;
444
445     WebContextClient m_client;
446     WebContextConnectionClient m_connectionClient;
447     std::unique_ptr<API::DownloadClient> m_downloadClient;
448     std::unique_ptr<API::HistoryClient> m_historyClient;
449
450 #if ENABLE(NETSCAPE_PLUGIN_API)
451     PluginInfoStore m_pluginInfoStore;
452 #endif
453     RefPtr<VisitedLinkProvider> m_visitedLinkProvider;
454     bool m_visitedLinksPopulated;
455
456     PlugInAutoStartProvider m_plugInAutoStartProvider;
457         
458     HashSet<String> m_schemesToRegisterAsEmptyDocument;
459     HashSet<String> m_schemesToRegisterAsSecure;
460     HashSet<String> m_schemesToSetDomainRelaxationForbiddenFor;
461     HashSet<String> m_schemesToRegisterAsLocal;
462     HashSet<String> m_schemesToRegisterAsNoAccess;
463     HashSet<String> m_schemesToRegisterAsDisplayIsolated;
464     HashSet<String> m_schemesToRegisterAsCORSEnabled;
465 #if ENABLE(CACHE_PARTITIONING)
466     HashSet<String> m_schemesToRegisterAsCachePartitioned;
467 #endif
468
469     bool m_alwaysUsesComplexTextCodePath;
470     bool m_shouldUseFontSmoothing;
471
472     // Messages that were posted before any pages were created.
473     // The client should use initialization messages instead, so that a restarted process would get the same state.
474     Vector<std::pair<String, RefPtr<API::Object>>> m_messagesToInjectedBundlePostedToEmptyContext;
475
476     CacheModel m_cacheModel;
477
478     bool m_memorySamplerEnabled;
479     double m_memorySamplerInterval;
480
481     RefPtr<WebIconDatabase> m_iconDatabase;
482 #if ENABLE(NETSCAPE_PLUGIN_API)
483     RefPtr<WebPluginSiteDataManager> m_pluginSiteDataManager;
484 #endif
485
486     RefPtr<StorageManager> m_storageManager;
487
488     typedef HashMap<const char*, RefPtr<WebContextSupplement>, PtrHash<const char*>> WebContextSupplementMap;
489     WebContextSupplementMap m_supplements;
490
491 #if USE(SOUP)
492     HTTPCookieAcceptPolicy m_initialHTTPCookieAcceptPolicy;
493 #endif
494
495 #if PLATFORM(MAC)
496     RetainPtr<NSObject> m_enhancedAccessibilityObserver;
497     RetainPtr<NSObject> m_automaticTextReplacementNotificationObserver;
498     RetainPtr<NSObject> m_automaticSpellingCorrectionNotificationObserver;
499 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
500     RetainPtr<NSObject> m_automaticQuoteSubstitutionNotificationObserver;
501     RetainPtr<NSObject> m_automaticDashSubstitutionNotificationObserver;
502 #endif
503 #endif
504
505     String m_overrideApplicationCacheDirectory;
506     String m_overrideDatabaseDirectory;
507     String m_overrideIconDatabasePath;
508     String m_overrideLocalStorageDirectory;
509     String m_overrideDiskCacheDirectory;
510     String m_overrideCookieStorageDirectory;
511
512     bool m_shouldUseTestingNetworkSession;
513
514     bool m_processTerminationEnabled;
515
516 #if ENABLE(NETWORK_PROCESS)
517     bool m_usesNetworkProcess;
518     RefPtr<NetworkProcessProxy> m_networkProcess;
519 #endif
520
521 #if ENABLE(DATABASE_PROCESS)
522     RefPtr<DatabaseProcessProxy> m_databaseProcess;
523 #endif
524     
525     HashMap<uint64_t, RefPtr<DictionaryCallback>> m_dictionaryCallbacks;
526     HashMap<uint64_t, RefPtr<StatisticsRequest>> m_statisticsRequests;
527
528 #if USE(SOUP)
529     bool m_ignoreTLSErrors;
530 #endif
531
532     bool m_memoryCacheDisabled;
533
534 #if PLATFORM(COCOA)
535     RetainPtr<NSMutableDictionary> m_bundleParameters;
536 #endif
537 };
538
539 template<typename T>
540 void WebContext::sendToNetworkingProcess(T&& message)
541 {
542     switch (m_processModel) {
543     case ProcessModelSharedSecondaryProcess:
544 #if ENABLE(NETWORK_PROCESS)
545         if (m_usesNetworkProcess) {
546             if (m_networkProcess && m_networkProcess->canSendMessage())
547                 m_networkProcess->send(std::forward<T>(message), 0);
548             return;
549         }
550 #endif
551         if (!m_processes.isEmpty() && m_processes[0]->canSendMessage())
552             m_processes[0]->send(std::forward<T>(message), 0);
553         return;
554     case ProcessModelMultipleSecondaryProcesses:
555 #if ENABLE(NETWORK_PROCESS)
556         if (m_networkProcess && m_networkProcess->canSendMessage())
557             m_networkProcess->send(std::forward<T>(message), 0);
558         return;
559 #else
560         break;
561 #endif
562     }
563     ASSERT_NOT_REACHED();
564 }
565
566 template<typename T>
567 void WebContext::sendToNetworkingProcessRelaunchingIfNecessary(T&& message)
568 {
569     switch (m_processModel) {
570     case ProcessModelSharedSecondaryProcess:
571 #if ENABLE(NETWORK_PROCESS)
572         if (m_usesNetworkProcess) {
573             ensureNetworkProcess();
574             m_networkProcess->send(std::forward<T>(message), 0);
575             return;
576         }
577 #endif
578         ensureSharedWebProcess();
579         m_processes[0]->send(std::forward<T>(message), 0);
580         return;
581     case ProcessModelMultipleSecondaryProcesses:
582 #if ENABLE(NETWORK_PROCESS)
583         ensureNetworkProcess();
584         m_networkProcess->send(std::forward<T>(message), 0);
585         return;
586 #else
587         break;
588 #endif
589     }
590     ASSERT_NOT_REACHED();
591 }
592
593 template<typename T>
594 void WebContext::sendToAllProcesses(const T& message)
595 {
596     size_t processCount = m_processes.size();
597     for (size_t i = 0; i < processCount; ++i) {
598         WebProcessProxy* process = m_processes[i].get();
599         if (process->canSendMessage())
600             process->send(T(message), 0);
601     }
602 }
603
604 template<typename T>
605 void WebContext::sendToAllProcessesRelaunchingThemIfNecessary(const T& message)
606 {
607 // FIXME (Multi-WebProcess): WebContext doesn't track processes that have exited, so it cannot relaunch these. Perhaps this functionality won't be needed in this mode.
608     if (m_processModel == ProcessModelSharedSecondaryProcess)
609         ensureSharedWebProcess();
610     sendToAllProcesses(message);
611 }
612
613 template<typename T>
614 void WebContext::sendToOneProcess(T&& message)
615 {
616     if (m_processModel == ProcessModelSharedSecondaryProcess)
617         ensureSharedWebProcess();
618
619     bool messageSent = false;
620     size_t processCount = m_processes.size();
621     for (size_t i = 0; i < processCount; ++i) {
622         WebProcessProxy* process = m_processes[i].get();
623         if (process->canSendMessage()) {
624             process->send(std::forward<T>(message), 0);
625             messageSent = true;
626             break;
627         }
628     }
629
630     if (!messageSent && m_processModel == ProcessModelMultipleSecondaryProcesses) {
631         warmInitialProcess();
632         RefPtr<WebProcessProxy> process = m_processes.last();
633         if (process->canSendMessage())
634             process->send(std::forward<T>(message), 0);
635     }
636 }
637
638 } // namespace WebKit
639
640 #endif // WebContext_h