• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010, 2011 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 #include "config.h"
27 #include "WebContext.h"
28 
29 #include "DownloadProxy.h"
30 #include "ImmutableArray.h"
31 #include "InjectedBundleMessageKinds.h"
32 #include "Logging.h"
33 #include "RunLoop.h"
34 #include "SandboxExtension.h"
35 #include "TextChecker.h"
36 #include "WKContextPrivate.h"
37 #include "WebApplicationCacheManagerProxy.h"
38 #include "WebContextMessageKinds.h"
39 #include "WebContextUserMessageCoders.h"
40 #include "WebCookieManagerProxy.h"
41 #include "WebCoreArgumentCoders.h"
42 #include "WebDatabaseManagerProxy.h"
43 #include "WebGeolocationManagerProxy.h"
44 #include "WebIconDatabase.h"
45 #include "WebKeyValueStorageManagerProxy.h"
46 #include "WebMediaCacheManagerProxy.h"
47 #include "WebPluginSiteDataManager.h"
48 #include "WebPageGroup.h"
49 #include "WebMemorySampler.h"
50 #include "WebProcessCreationParameters.h"
51 #include "WebProcessMessages.h"
52 #include "WebProcessProxy.h"
53 #include "WebResourceCacheManagerProxy.h"
54 #include <WebCore/Language.h>
55 #include <WebCore/LinkHash.h>
56 #include <WebCore/Logging.h>
57 #include <WebCore/ResourceRequest.h>
58 #include <wtf/CurrentTime.h>
59 
60 #ifndef NDEBUG
61 #include <wtf/RefCountedLeakCounter.h>
62 #endif
63 
64 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, process()->connection())
65 
66 using namespace WebCore;
67 
68 namespace WebKit {
69 
70 #ifndef NDEBUG
71 static WTF::RefCountedLeakCounter webContextCounter("WebContext");
72 #endif
73 
sharedProcessContext()74 WebContext* WebContext::sharedProcessContext()
75 {
76     WTF::initializeMainThread();
77     RunLoop::initializeMainRunLoop();
78     static WebContext* context = adoptRef(new WebContext(ProcessModelSharedSecondaryProcess, String())).leakRef();
79     return context;
80 }
81 
sharedThreadContext()82 WebContext* WebContext::sharedThreadContext()
83 {
84     RunLoop::initializeMainRunLoop();
85     static WebContext* context = adoptRef(new WebContext(ProcessModelSharedSecondaryThread, String())).leakRef();
86     return context;
87 }
88 
create(const String & injectedBundlePath)89 PassRefPtr<WebContext> WebContext::create(const String& injectedBundlePath)
90 {
91     WTF::initializeMainThread();
92     RunLoop::initializeMainRunLoop();
93     return adoptRef(new WebContext(ProcessModelSecondaryProcess, injectedBundlePath));
94 }
95 
contexts()96 static Vector<WebContext*>& contexts()
97 {
98     DEFINE_STATIC_LOCAL(Vector<WebContext*>, contexts, ());
99 
100     return contexts;
101 }
102 
allContexts()103 const Vector<WebContext*>& WebContext::allContexts()
104 {
105     return contexts();
106 }
107 
WebContext(ProcessModel processModel,const String & injectedBundlePath)108 WebContext::WebContext(ProcessModel processModel, const String& injectedBundlePath)
109     : m_processModel(processModel)
110     , m_defaultPageGroup(WebPageGroup::create())
111     , m_injectedBundlePath(injectedBundlePath)
112     , m_visitedLinkProvider(this)
113     , m_alwaysUsesComplexTextCodePath(false)
114     , m_cacheModel(CacheModelDocumentViewer)
115     , m_memorySamplerEnabled(false)
116     , m_memorySamplerInterval(1400.0)
117     , m_applicationCacheManagerProxy(WebApplicationCacheManagerProxy::create(this))
118     , m_cookieManagerProxy(WebCookieManagerProxy::create(this))
119     , m_databaseManagerProxy(WebDatabaseManagerProxy::create(this))
120     , m_geolocationManagerProxy(WebGeolocationManagerProxy::create(this))
121     , m_iconDatabase(WebIconDatabase::create(this))
122     , m_keyValueStorageManagerProxy(WebKeyValueStorageManagerProxy::create(this))
123     , m_mediaCacheManagerProxy(WebMediaCacheManagerProxy::create(this))
124     , m_pluginSiteDataManager(WebPluginSiteDataManager::create(this))
125     , m_resourceCacheManagerProxy(WebResourceCacheManagerProxy::create(this))
126 #if PLATFORM(WIN)
127     , m_shouldPaintNativeControls(true)
128     , m_initialHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicyAlways)
129 #endif
130     , m_processTerminationEnabled(true)
131 {
132 #ifndef NDEBUG
133     WebKit::initializeLogChannelsIfNecessary();
134 #endif
135 
136     contexts().append(this);
137 
138     addLanguageChangeObserver(this, languageChanged);
139 
140     WebCore::InitializeLoggingChannelsIfNecessary();
141 
142 #ifndef NDEBUG
143     webContextCounter.increment();
144 #endif
145 }
146 
~WebContext()147 WebContext::~WebContext()
148 {
149     ASSERT(contexts().find(this) != notFound);
150     contexts().remove(contexts().find(this));
151 
152     removeLanguageChangeObserver(this);
153 
154     m_applicationCacheManagerProxy->invalidate();
155     m_applicationCacheManagerProxy->clearContext();
156 
157     m_cookieManagerProxy->invalidate();
158     m_cookieManagerProxy->clearContext();
159 
160     m_databaseManagerProxy->invalidate();
161     m_databaseManagerProxy->clearContext();
162 
163     m_geolocationManagerProxy->invalidate();
164     m_geolocationManagerProxy->clearContext();
165 
166     m_iconDatabase->invalidate();
167     m_iconDatabase->clearContext();
168 
169     m_keyValueStorageManagerProxy->invalidate();
170     m_keyValueStorageManagerProxy->clearContext();
171 
172     m_mediaCacheManagerProxy->invalidate();
173     m_mediaCacheManagerProxy->clearContext();
174 
175     m_pluginSiteDataManager->invalidate();
176     m_pluginSiteDataManager->clearContext();
177 
178     m_resourceCacheManagerProxy->invalidate();
179     m_resourceCacheManagerProxy->clearContext();
180 
181     platformInvalidateContext();
182 
183 #ifndef NDEBUG
184     webContextCounter.decrement();
185 #endif
186 }
187 
initializeInjectedBundleClient(const WKContextInjectedBundleClient * client)188 void WebContext::initializeInjectedBundleClient(const WKContextInjectedBundleClient* client)
189 {
190     m_injectedBundleClient.initialize(client);
191 }
192 
initializeHistoryClient(const WKContextHistoryClient * client)193 void WebContext::initializeHistoryClient(const WKContextHistoryClient* client)
194 {
195     m_historyClient.initialize(client);
196 
197     sendToAllProcesses(Messages::WebProcess::SetShouldTrackVisitedLinks(m_historyClient.shouldTrackVisitedLinks()));
198 }
199 
initializeDownloadClient(const WKContextDownloadClient * client)200 void WebContext::initializeDownloadClient(const WKContextDownloadClient* client)
201 {
202     m_downloadClient.initialize(client);
203 }
204 
languageChanged(void * context)205 void WebContext::languageChanged(void* context)
206 {
207     static_cast<WebContext*>(context)->languageChanged();
208 }
209 
languageChanged()210 void WebContext::languageChanged()
211 {
212     sendToAllProcesses(Messages::WebProcess::LanguageChanged(defaultLanguage()));
213 }
214 
ensureWebProcess()215 void WebContext::ensureWebProcess()
216 {
217     if (m_process)
218         return;
219 
220     m_process = WebProcessProxy::create(this);
221 
222     WebProcessCreationParameters parameters;
223 
224     parameters.applicationCacheDirectory = applicationCacheDirectory();
225 
226     if (!injectedBundlePath().isEmpty()) {
227         parameters.injectedBundlePath = injectedBundlePath();
228 
229         SandboxExtension::createHandle(parameters.injectedBundlePath, SandboxExtension::ReadOnly, parameters.injectedBundlePathExtensionHandle);
230     }
231 
232     parameters.shouldTrackVisitedLinks = m_historyClient.shouldTrackVisitedLinks();
233     parameters.cacheModel = m_cacheModel;
234     parameters.languageCode = defaultLanguage();
235     parameters.applicationCacheDirectory = applicationCacheDirectory();
236     parameters.databaseDirectory = databaseDirectory();
237     parameters.localStorageDirectory = localStorageDirectory();
238 #if PLATFORM(MAC)
239     parameters.presenterApplicationPid = getpid();
240 #endif
241 
242     copyToVector(m_schemesToRegisterAsEmptyDocument, parameters.urlSchemesRegistererdAsEmptyDocument);
243     copyToVector(m_schemesToRegisterAsSecure, parameters.urlSchemesRegisteredAsSecure);
244     copyToVector(m_schemesToSetDomainRelaxationForbiddenFor, parameters.urlSchemesForWhichDomainRelaxationIsForbidden);
245 
246     parameters.shouldAlwaysUseComplexTextCodePath = m_alwaysUsesComplexTextCodePath;
247 
248     parameters.iconDatabaseEnabled = !iconDatabasePath().isEmpty();
249 
250     parameters.textCheckerState = TextChecker::state();
251 
252     parameters.defaultRequestTimeoutInterval = WebURLRequest::defaultTimeoutInterval();
253 
254     // Add any platform specific parameters
255     platformInitializeWebProcess(parameters);
256 
257     m_process->send(Messages::WebProcess::InitializeWebProcess(parameters, WebContextUserMessageEncoder(m_injectedBundleInitializationUserData.get())), 0);
258 
259     for (size_t i = 0; i != m_pendingMessagesToPostToInjectedBundle.size(); ++i) {
260         pair<String, RefPtr<APIObject> >& message = m_pendingMessagesToPostToInjectedBundle[i];
261         m_process->deprecatedSend(InjectedBundleMessage::PostMessage, 0, CoreIPC::In(message.first, WebContextUserMessageEncoder(message.second.get())));
262     }
263     m_pendingMessagesToPostToInjectedBundle.clear();
264 }
265 
enableProcessTermination()266 void WebContext::enableProcessTermination()
267 {
268     m_processTerminationEnabled = true;
269     if (shouldTerminate(m_process.get()))
270         m_process->terminate();
271 }
272 
shouldTerminate(WebProcessProxy * process)273 bool WebContext::shouldTerminate(WebProcessProxy* process)
274 {
275     // FIXME: Once we support multiple processes per context, this assertion won't hold.
276     ASSERT(process == m_process);
277 
278     if (!m_processTerminationEnabled)
279         return false;
280 
281     if (!m_downloads.isEmpty())
282         return false;
283 
284     if (!m_applicationCacheManagerProxy->shouldTerminate(process))
285         return false;
286     if (!m_cookieManagerProxy->shouldTerminate(process))
287         return false;
288     if (!m_databaseManagerProxy->shouldTerminate(process))
289         return false;
290     if (!m_keyValueStorageManagerProxy->shouldTerminate(process))
291         return false;
292     if (!m_mediaCacheManagerProxy->shouldTerminate(process))
293         return false;
294     if (!m_pluginSiteDataManager->shouldTerminate(process))
295         return false;
296     if (!m_resourceCacheManagerProxy->shouldTerminate(process))
297         return false;
298 
299     return true;
300 }
301 
processDidFinishLaunching(WebProcessProxy * process)302 void WebContext::processDidFinishLaunching(WebProcessProxy* process)
303 {
304     // FIXME: Once we support multiple processes per context, this assertion won't hold.
305     ASSERT_UNUSED(process, process == m_process);
306 
307     m_visitedLinkProvider.processDidFinishLaunching();
308 
309     // Sometimes the memorySampler gets initialized after process initialization has happened but before the process has finished launching
310     // so check if it needs to be started here
311     if (m_memorySamplerEnabled) {
312         SandboxExtension::Handle sampleLogSandboxHandle;
313         double now = WTF::currentTime();
314         String sampleLogFilePath = String::format("WebProcess%llu", static_cast<uint64_t>(now));
315         sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::WriteOnly, sampleLogSandboxHandle);
316 
317         m_process->send(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, m_memorySamplerInterval), 0);
318     }
319 }
320 
disconnectProcess(WebProcessProxy * process)321 void WebContext::disconnectProcess(WebProcessProxy* process)
322 {
323     // FIXME: Once we support multiple processes per context, this assertion won't hold.
324     ASSERT_UNUSED(process, process == m_process);
325 
326     m_visitedLinkProvider.processDidClose();
327 
328     // Invalidate all outstanding downloads.
329     for (HashMap<uint64_t, RefPtr<DownloadProxy> >::iterator::Values it = m_downloads.begin().values(), end = m_downloads.end().values(); it != end; ++it) {
330         (*it)->processDidClose();
331         (*it)->invalidate();
332     }
333 
334     m_downloads.clear();
335 
336     m_applicationCacheManagerProxy->invalidate();
337     m_cookieManagerProxy->invalidate();
338     m_databaseManagerProxy->invalidate();
339     m_geolocationManagerProxy->invalidate();
340     m_keyValueStorageManagerProxy->invalidate();
341     m_mediaCacheManagerProxy->invalidate();
342     m_resourceCacheManagerProxy->invalidate();
343 
344     // When out of process plug-ins are enabled, we don't want to invalidate the plug-in site data
345     // manager just because the web process crashes since it's not involved.
346 #if !ENABLE(PLUGIN_PROCESS)
347     m_pluginSiteDataManager->invalidate();
348 #endif
349 
350     // This can cause the web context to be destroyed.
351     m_process = 0;
352 }
353 
createWebPage(PageClient * pageClient,WebPageGroup * pageGroup)354 PassRefPtr<WebPageProxy> WebContext::createWebPage(PageClient* pageClient, WebPageGroup* pageGroup)
355 {
356     ensureWebProcess();
357 
358     if (!pageGroup)
359         pageGroup = m_defaultPageGroup.get();
360 
361     return m_process->createWebPage(pageClient, this, pageGroup);
362 }
363 
relaunchProcessIfNecessary()364 WebProcessProxy* WebContext::relaunchProcessIfNecessary()
365 {
366     ensureWebProcess();
367 
368     ASSERT(m_process);
369     return m_process.get();
370 }
371 
download(WebPageProxy * initiatingPage,const ResourceRequest & request)372 DownloadProxy* WebContext::download(WebPageProxy* initiatingPage, const ResourceRequest& request)
373 {
374     DownloadProxy* download = createDownloadProxy();
375     uint64_t initiatingPageID = initiatingPage ? initiatingPage->pageID() : 0;
376 
377     process()->send(Messages::WebProcess::DownloadRequest(download->downloadID(), initiatingPageID, request), 0);
378     return download;
379 }
380 
postMessageToInjectedBundle(const String & messageName,APIObject * messageBody)381 void WebContext::postMessageToInjectedBundle(const String& messageName, APIObject* messageBody)
382 {
383     if (!m_process || !m_process->canSendMessage()) {
384         m_pendingMessagesToPostToInjectedBundle.append(make_pair(messageName, messageBody));
385         return;
386     }
387 
388     // FIXME: We should consider returning false from this function if the messageBody cannot
389     // be encoded.
390     m_process->deprecatedSend(InjectedBundleMessage::PostMessage, 0, CoreIPC::In(messageName, WebContextUserMessageEncoder(messageBody)));
391 }
392 
393 // InjectedBundle client
394 
didReceiveMessageFromInjectedBundle(const String & messageName,APIObject * messageBody)395 void WebContext::didReceiveMessageFromInjectedBundle(const String& messageName, APIObject* messageBody)
396 {
397     m_injectedBundleClient.didReceiveMessageFromInjectedBundle(this, messageName, messageBody);
398 }
399 
didReceiveSynchronousMessageFromInjectedBundle(const String & messageName,APIObject * messageBody,RefPtr<APIObject> & returnData)400 void WebContext::didReceiveSynchronousMessageFromInjectedBundle(const String& messageName, APIObject* messageBody, RefPtr<APIObject>& returnData)
401 {
402     m_injectedBundleClient.didReceiveSynchronousMessageFromInjectedBundle(this, messageName, messageBody, returnData);
403 }
404 
405 // HistoryClient
406 
didNavigateWithNavigationData(uint64_t pageID,const WebNavigationDataStore & store,uint64_t frameID)407 void WebContext::didNavigateWithNavigationData(uint64_t pageID, const WebNavigationDataStore& store, uint64_t frameID)
408 {
409     WebFrameProxy* frame = m_process->webFrame(frameID);
410     MESSAGE_CHECK(frame);
411     if (!frame->page())
412         return;
413 
414     m_historyClient.didNavigateWithNavigationData(this, frame->page(), store, frame);
415 }
416 
didPerformClientRedirect(uint64_t pageID,const String & sourceURLString,const String & destinationURLString,uint64_t frameID)417 void WebContext::didPerformClientRedirect(uint64_t pageID, const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
418 {
419     WebFrameProxy* frame = m_process->webFrame(frameID);
420     MESSAGE_CHECK(frame);
421     if (!frame->page())
422         return;
423 
424     m_historyClient.didPerformClientRedirect(this, frame->page(), sourceURLString, destinationURLString, frame);
425 }
426 
didPerformServerRedirect(uint64_t pageID,const String & sourceURLString,const String & destinationURLString,uint64_t frameID)427 void WebContext::didPerformServerRedirect(uint64_t pageID, const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
428 {
429     WebFrameProxy* frame = m_process->webFrame(frameID);
430     MESSAGE_CHECK(frame);
431     if (!frame->page())
432         return;
433 
434     m_historyClient.didPerformServerRedirect(this, frame->page(), sourceURLString, destinationURLString, frame);
435 }
436 
didUpdateHistoryTitle(uint64_t pageID,const String & title,const String & url,uint64_t frameID)437 void WebContext::didUpdateHistoryTitle(uint64_t pageID, const String& title, const String& url, uint64_t frameID)
438 {
439     WebFrameProxy* frame = m_process->webFrame(frameID);
440     MESSAGE_CHECK(frame);
441     if (!frame->page())
442         return;
443 
444     m_historyClient.didUpdateHistoryTitle(this, frame->page(), title, url, frame);
445 }
446 
populateVisitedLinks()447 void WebContext::populateVisitedLinks()
448 {
449     m_historyClient.populateVisitedLinks(this);
450 }
451 
statistics()452 WebContext::Statistics& WebContext::statistics()
453 {
454     static Statistics statistics = Statistics();
455 
456     return statistics;
457 }
458 
setAdditionalPluginsDirectory(const String & directory)459 void WebContext::setAdditionalPluginsDirectory(const String& directory)
460 {
461     Vector<String> directories;
462     directories.append(directory);
463 
464     m_pluginInfoStore.setAdditionalPluginsDirectories(directories);
465 }
466 
setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)467 void WebContext::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
468 {
469     m_alwaysUsesComplexTextCodePath = alwaysUseComplexText;
470     sendToAllProcesses(Messages::WebProcess::SetAlwaysUsesComplexTextCodePath(alwaysUseComplexText));
471 }
472 
registerURLSchemeAsEmptyDocument(const String & urlScheme)473 void WebContext::registerURLSchemeAsEmptyDocument(const String& urlScheme)
474 {
475     m_schemesToRegisterAsEmptyDocument.add(urlScheme);
476     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsEmptyDocument(urlScheme));
477 }
478 
registerURLSchemeAsSecure(const String & urlScheme)479 void WebContext::registerURLSchemeAsSecure(const String& urlScheme)
480 {
481     m_schemesToRegisterAsSecure.add(urlScheme);
482     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsSecure(urlScheme));
483 }
484 
setDomainRelaxationForbiddenForURLScheme(const String & urlScheme)485 void WebContext::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme)
486 {
487     m_schemesToSetDomainRelaxationForbiddenFor.add(urlScheme);
488     sendToAllProcesses(Messages::WebProcess::SetDomainRelaxationForbiddenForURLScheme(urlScheme));
489 }
490 
setCacheModel(CacheModel cacheModel)491 void WebContext::setCacheModel(CacheModel cacheModel)
492 {
493     m_cacheModel = cacheModel;
494     sendToAllProcesses(Messages::WebProcess::SetCacheModel(static_cast<uint32_t>(m_cacheModel)));
495 }
496 
setDefaultRequestTimeoutInterval(double timeoutInterval)497 void WebContext::setDefaultRequestTimeoutInterval(double timeoutInterval)
498 {
499     sendToAllProcesses(Messages::WebProcess::SetDefaultRequestTimeoutInterval(timeoutInterval));
500 }
501 
addVisitedLink(const String & visitedURL)502 void WebContext::addVisitedLink(const String& visitedURL)
503 {
504     if (visitedURL.isEmpty())
505         return;
506 
507     LinkHash linkHash = visitedLinkHash(visitedURL.characters(), visitedURL.length());
508     addVisitedLinkHash(linkHash);
509 }
510 
addVisitedLinkHash(LinkHash linkHash)511 void WebContext::addVisitedLinkHash(LinkHash linkHash)
512 {
513     m_visitedLinkProvider.addVisitedLink(linkHash);
514 }
515 
getPlugins(bool refresh,Vector<PluginInfo> & plugins)516 void WebContext::getPlugins(bool refresh, Vector<PluginInfo>& plugins)
517 {
518     if (refresh)
519         pluginInfoStore()->refresh();
520     pluginInfoStore()->getPlugins(plugins);
521 }
522 
getPluginPath(const String & mimeType,const String & urlString,String & pluginPath)523 void WebContext::getPluginPath(const String& mimeType, const String& urlString, String& pluginPath)
524 {
525     String newMimeType = mimeType.lower();
526 
527     PluginInfoStore::Plugin plugin = pluginInfoStore()->findPlugin(newMimeType, KURL(ParsedURLString, urlString));
528     if (!plugin.path)
529         return;
530 
531     pluginPath = plugin.path;
532 }
533 
534 #if !ENABLE(PLUGIN_PROCESS)
didGetSitesWithPluginData(const Vector<String> & sites,uint64_t callbackID)535 void WebContext::didGetSitesWithPluginData(const Vector<String>& sites, uint64_t callbackID)
536 {
537     m_pluginSiteDataManager->didGetSitesWithData(sites, callbackID);
538 }
539 
didClearPluginSiteData(uint64_t callbackID)540 void WebContext::didClearPluginSiteData(uint64_t callbackID)
541 {
542     m_pluginSiteDataManager->didClearSiteData(callbackID);
543 }
544 #endif
545 
createDownloadProxy()546 DownloadProxy* WebContext::createDownloadProxy()
547 {
548     RefPtr<DownloadProxy> downloadProxy = DownloadProxy::create(this);
549     m_downloads.set(downloadProxy->downloadID(), downloadProxy);
550     return downloadProxy.get();
551 }
552 
downloadFinished(DownloadProxy * downloadProxy)553 void WebContext::downloadFinished(DownloadProxy* downloadProxy)
554 {
555     ASSERT(m_downloads.contains(downloadProxy->downloadID()));
556 
557     downloadProxy->invalidate();
558     m_downloads.remove(downloadProxy->downloadID());
559 }
560 
561 // FIXME: This is not the ideal place for this function.
pdfAndPostScriptMIMETypes()562 HashSet<String, CaseFoldingHash> WebContext::pdfAndPostScriptMIMETypes()
563 {
564     HashSet<String, CaseFoldingHash> mimeTypes;
565 
566     mimeTypes.add("application/pdf");
567     mimeTypes.add("application/postscript");
568     mimeTypes.add("text/pdf");
569 
570     return mimeTypes;
571 }
572 
didReceiveMessage(CoreIPC::Connection * connection,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments)573 void WebContext::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
574 {
575     if (messageID.is<CoreIPC::MessageClassWebContext>()) {
576         didReceiveWebContextMessage(connection, messageID, arguments);
577         return;
578     }
579 
580     if (messageID.is<CoreIPC::MessageClassDownloadProxy>()) {
581         if (DownloadProxy* downloadProxy = m_downloads.get(arguments->destinationID()).get())
582             downloadProxy->didReceiveDownloadProxyMessage(connection, messageID, arguments);
583 
584         return;
585     }
586 
587     if (messageID.is<CoreIPC::MessageClassWebApplicationCacheManagerProxy>()) {
588         m_applicationCacheManagerProxy->didReceiveMessage(connection, messageID, arguments);
589         return;
590     }
591 
592     if (messageID.is<CoreIPC::MessageClassWebCookieManagerProxy>()) {
593         m_cookieManagerProxy->didReceiveMessage(connection, messageID, arguments);
594         return;
595     }
596 
597     if (messageID.is<CoreIPC::MessageClassWebDatabaseManagerProxy>()) {
598         m_databaseManagerProxy->didReceiveWebDatabaseManagerProxyMessage(connection, messageID, arguments);
599         return;
600     }
601 
602     if (messageID.is<CoreIPC::MessageClassWebGeolocationManagerProxy>()) {
603         m_geolocationManagerProxy->didReceiveMessage(connection, messageID, arguments);
604         return;
605     }
606 
607     if (messageID.is<CoreIPC::MessageClassWebIconDatabase>()) {
608         m_iconDatabase->didReceiveMessage(connection, messageID, arguments);
609         return;
610     }
611 
612     if (messageID.is<CoreIPC::MessageClassWebKeyValueStorageManagerProxy>()) {
613         m_keyValueStorageManagerProxy->didReceiveMessage(connection, messageID, arguments);
614         return;
615     }
616 
617     if (messageID.is<CoreIPC::MessageClassWebMediaCacheManagerProxy>()) {
618         m_mediaCacheManagerProxy->didReceiveMessage(connection, messageID, arguments);
619         return;
620     }
621 
622     if (messageID.is<CoreIPC::MessageClassWebResourceCacheManagerProxy>()) {
623         m_resourceCacheManagerProxy->didReceiveWebResourceCacheManagerProxyMessage(connection, messageID, arguments);
624         return;
625     }
626 
627     switch (messageID.get<WebContextLegacyMessage::Kind>()) {
628         case WebContextLegacyMessage::PostMessage: {
629             String messageName;
630             RefPtr<APIObject> messageBody;
631             WebContextUserMessageDecoder messageDecoder(messageBody, this);
632             if (!arguments->decode(CoreIPC::Out(messageName, messageDecoder)))
633                 return;
634 
635             didReceiveMessageFromInjectedBundle(messageName, messageBody.get());
636             return;
637         }
638         case WebContextLegacyMessage::PostSynchronousMessage:
639             ASSERT_NOT_REACHED();
640     }
641 
642     ASSERT_NOT_REACHED();
643 }
644 
didReceiveSyncMessage(CoreIPC::Connection * connection,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments,CoreIPC::ArgumentEncoder * reply)645 CoreIPC::SyncReplyMode WebContext::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply)
646 {
647     if (messageID.is<CoreIPC::MessageClassWebContext>())
648         return didReceiveSyncWebContextMessage(connection, messageID, arguments, reply);
649 
650     if (messageID.is<CoreIPC::MessageClassDownloadProxy>()) {
651         if (DownloadProxy* downloadProxy = m_downloads.get(arguments->destinationID()).get())
652             return downloadProxy->didReceiveSyncDownloadProxyMessage(connection, messageID, arguments, reply);
653 
654         return CoreIPC::AutomaticReply;
655     }
656 
657     if (messageID.is<CoreIPC::MessageClassWebIconDatabase>())
658         return m_iconDatabase->didReceiveSyncMessage(connection, messageID, arguments, reply);
659 
660     switch (messageID.get<WebContextLegacyMessage::Kind>()) {
661         case WebContextLegacyMessage::PostSynchronousMessage: {
662             // FIXME: We should probably encode something in the case that the arguments do not decode correctly.
663 
664             String messageName;
665             RefPtr<APIObject> messageBody;
666             WebContextUserMessageDecoder messageDecoder(messageBody, this);
667             if (!arguments->decode(CoreIPC::Out(messageName, messageDecoder)))
668                 return CoreIPC::AutomaticReply;
669 
670             RefPtr<APIObject> returnData;
671             didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody.get(), returnData);
672             reply->encode(CoreIPC::In(WebContextUserMessageEncoder(returnData.get())));
673             return CoreIPC::AutomaticReply;
674         }
675         case WebContextLegacyMessage::PostMessage:
676             ASSERT_NOT_REACHED();
677     }
678 
679     return CoreIPC::AutomaticReply;
680 }
681 
setEnhancedAccessibility(bool flag)682 void WebContext::setEnhancedAccessibility(bool flag)
683 {
684     sendToAllProcesses(Messages::WebProcess::SetEnhancedAccessibility(flag));
685 }
686 
startMemorySampler(const double interval)687 void WebContext::startMemorySampler(const double interval)
688 {
689     // For new WebProcesses we will also want to start the Memory Sampler
690     m_memorySamplerEnabled = true;
691     m_memorySamplerInterval = interval;
692 
693     // For UIProcess
694 #if ENABLE(MEMORY_SAMPLER)
695     WebMemorySampler::shared()->start(interval);
696 #endif
697 
698     // For WebProcess
699     SandboxExtension::Handle sampleLogSandboxHandle;
700     double now = WTF::currentTime();
701     String sampleLogFilePath = String::format("WebProcess%llu", static_cast<uint64_t>(now));
702     sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::WriteOnly, sampleLogSandboxHandle);
703 
704     sendToAllProcesses(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, interval));
705 }
706 
stopMemorySampler()707 void WebContext::stopMemorySampler()
708 {
709     // For WebProcess
710     m_memorySamplerEnabled = false;
711 
712     // For UIProcess
713 #if ENABLE(MEMORY_SAMPLER)
714     WebMemorySampler::shared()->stop();
715 #endif
716 
717     sendToAllProcesses(Messages::WebProcess::StopMemorySampler());
718 }
719 
databaseDirectory() const720 String WebContext::databaseDirectory() const
721 {
722     if (!m_overrideDatabaseDirectory.isEmpty())
723         return m_overrideDatabaseDirectory;
724 
725     return platformDefaultDatabaseDirectory();
726 }
727 
setIconDatabasePath(const String & path)728 void WebContext::setIconDatabasePath(const String& path)
729 {
730     m_overrideIconDatabasePath = path;
731     m_iconDatabase->setDatabasePath(path);
732 }
733 
iconDatabasePath() const734 String WebContext::iconDatabasePath() const
735 {
736     if (!m_overrideIconDatabasePath.isEmpty())
737         return m_overrideIconDatabasePath;
738 
739     return platformDefaultIconDatabasePath();
740 }
741 
localStorageDirectory() const742 String WebContext::localStorageDirectory() const
743 {
744     if (!m_overrideLocalStorageDirectory.isEmpty())
745         return m_overrideLocalStorageDirectory;
746 
747     return platformDefaultLocalStorageDirectory();
748 }
749 
setHTTPPipeliningEnabled(bool enabled)750 void WebContext::setHTTPPipeliningEnabled(bool enabled)
751 {
752 #if PLATFORM(MAC)
753     ResourceRequest::setHTTPPipeliningEnabled(enabled);
754 #endif
755 }
756 
httpPipeliningEnabled()757 bool WebContext::httpPipeliningEnabled()
758 {
759 #if PLATFORM(MAC)
760     return ResourceRequest::httpPipeliningEnabled();
761 #else
762     return false;
763 #endif
764 }
765 
766 } // namespace WebKit
767