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 if (!parameters.applicationCacheDirectory.isEmpty())
226 SandboxExtension::createHandle(parameters.applicationCacheDirectory, SandboxExtension::ReadWrite, parameters.applicationCacheDirectoryExtensionHandle);
227
228 if (!injectedBundlePath().isEmpty()) {
229 parameters.injectedBundlePath = injectedBundlePath();
230
231 SandboxExtension::createHandle(parameters.injectedBundlePath, SandboxExtension::ReadOnly, parameters.injectedBundlePathExtensionHandle);
232 }
233
234 parameters.shouldTrackVisitedLinks = m_historyClient.shouldTrackVisitedLinks();
235 parameters.cacheModel = m_cacheModel;
236 parameters.languageCode = defaultLanguage();
237 parameters.applicationCacheDirectory = applicationCacheDirectory();
238 parameters.databaseDirectory = databaseDirectory();
239 parameters.localStorageDirectory = localStorageDirectory();
240 #if PLATFORM(MAC)
241 parameters.presenterApplicationPid = getpid();
242 #endif
243
244 copyToVector(m_schemesToRegisterAsEmptyDocument, parameters.urlSchemesRegistererdAsEmptyDocument);
245 copyToVector(m_schemesToRegisterAsSecure, parameters.urlSchemesRegisteredAsSecure);
246 copyToVector(m_schemesToSetDomainRelaxationForbiddenFor, parameters.urlSchemesForWhichDomainRelaxationIsForbidden);
247
248 parameters.shouldAlwaysUseComplexTextCodePath = m_alwaysUsesComplexTextCodePath;
249
250 parameters.iconDatabaseEnabled = !iconDatabasePath().isEmpty();
251
252 parameters.textCheckerState = TextChecker::state();
253
254 parameters.defaultRequestTimeoutInterval = WebURLRequest::defaultTimeoutInterval();
255
256 // Add any platform specific parameters
257 platformInitializeWebProcess(parameters);
258
259 m_process->send(Messages::WebProcess::InitializeWebProcess(parameters, WebContextUserMessageEncoder(m_injectedBundleInitializationUserData.get())), 0);
260
261 for (size_t i = 0; i != m_pendingMessagesToPostToInjectedBundle.size(); ++i) {
262 pair<String, RefPtr<APIObject> >& message = m_pendingMessagesToPostToInjectedBundle[i];
263 m_process->deprecatedSend(InjectedBundleMessage::PostMessage, 0, CoreIPC::In(message.first, WebContextUserMessageEncoder(message.second.get())));
264 }
265 m_pendingMessagesToPostToInjectedBundle.clear();
266 }
267
enableProcessTermination()268 void WebContext::enableProcessTermination()
269 {
270 m_processTerminationEnabled = true;
271 if (shouldTerminate(m_process.get()))
272 m_process->terminate();
273 }
274
shouldTerminate(WebProcessProxy * process)275 bool WebContext::shouldTerminate(WebProcessProxy* process)
276 {
277 // FIXME: Once we support multiple processes per context, this assertion won't hold.
278 ASSERT(process == m_process);
279
280 if (!m_processTerminationEnabled)
281 return false;
282
283 if (!m_downloads.isEmpty())
284 return false;
285
286 if (!m_applicationCacheManagerProxy->shouldTerminate(process))
287 return false;
288 if (!m_cookieManagerProxy->shouldTerminate(process))
289 return false;
290 if (!m_databaseManagerProxy->shouldTerminate(process))
291 return false;
292 if (!m_keyValueStorageManagerProxy->shouldTerminate(process))
293 return false;
294 if (!m_mediaCacheManagerProxy->shouldTerminate(process))
295 return false;
296 if (!m_pluginSiteDataManager->shouldTerminate(process))
297 return false;
298 if (!m_resourceCacheManagerProxy->shouldTerminate(process))
299 return false;
300
301 return true;
302 }
303
processDidFinishLaunching(WebProcessProxy * process)304 void WebContext::processDidFinishLaunching(WebProcessProxy* process)
305 {
306 // FIXME: Once we support multiple processes per context, this assertion won't hold.
307 ASSERT_UNUSED(process, process == m_process);
308
309 m_visitedLinkProvider.processDidFinishLaunching();
310
311 // Sometimes the memorySampler gets initialized after process initialization has happened but before the process has finished launching
312 // so check if it needs to be started here
313 if (m_memorySamplerEnabled) {
314 SandboxExtension::Handle sampleLogSandboxHandle;
315 double now = WTF::currentTime();
316 String sampleLogFilePath = String::format("WebProcess%llu", static_cast<uint64_t>(now));
317 sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::WriteOnly, sampleLogSandboxHandle);
318
319 m_process->send(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, m_memorySamplerInterval), 0);
320 }
321 }
322
disconnectProcess(WebProcessProxy * process)323 void WebContext::disconnectProcess(WebProcessProxy* process)
324 {
325 // FIXME: Once we support multiple processes per context, this assertion won't hold.
326 ASSERT_UNUSED(process, process == m_process);
327
328 m_visitedLinkProvider.processDidClose();
329
330 // Invalidate all outstanding downloads.
331 for (HashMap<uint64_t, RefPtr<DownloadProxy> >::iterator::Values it = m_downloads.begin().values(), end = m_downloads.end().values(); it != end; ++it) {
332 (*it)->processDidClose();
333 (*it)->invalidate();
334 }
335
336 m_downloads.clear();
337
338 m_applicationCacheManagerProxy->invalidate();
339 m_cookieManagerProxy->invalidate();
340 m_databaseManagerProxy->invalidate();
341 m_geolocationManagerProxy->invalidate();
342 m_keyValueStorageManagerProxy->invalidate();
343 m_mediaCacheManagerProxy->invalidate();
344 m_resourceCacheManagerProxy->invalidate();
345
346 // When out of process plug-ins are enabled, we don't want to invalidate the plug-in site data
347 // manager just because the web process crashes since it's not involved.
348 #if !ENABLE(PLUGIN_PROCESS)
349 m_pluginSiteDataManager->invalidate();
350 #endif
351
352 // This can cause the web context to be destroyed.
353 m_process = 0;
354 }
355
createWebPage(PageClient * pageClient,WebPageGroup * pageGroup)356 PassRefPtr<WebPageProxy> WebContext::createWebPage(PageClient* pageClient, WebPageGroup* pageGroup)
357 {
358 ensureWebProcess();
359
360 if (!pageGroup)
361 pageGroup = m_defaultPageGroup.get();
362
363 return m_process->createWebPage(pageClient, this, pageGroup);
364 }
365
relaunchProcessIfNecessary()366 WebProcessProxy* WebContext::relaunchProcessIfNecessary()
367 {
368 ensureWebProcess();
369
370 ASSERT(m_process);
371 return m_process.get();
372 }
373
download(WebPageProxy * initiatingPage,const ResourceRequest & request)374 DownloadProxy* WebContext::download(WebPageProxy* initiatingPage, const ResourceRequest& request)
375 {
376 DownloadProxy* download = createDownloadProxy();
377 uint64_t initiatingPageID = initiatingPage ? initiatingPage->pageID() : 0;
378
379 process()->send(Messages::WebProcess::DownloadRequest(download->downloadID(), initiatingPageID, request), 0);
380 return download;
381 }
382
postMessageToInjectedBundle(const String & messageName,APIObject * messageBody)383 void WebContext::postMessageToInjectedBundle(const String& messageName, APIObject* messageBody)
384 {
385 if (!m_process || !m_process->canSendMessage()) {
386 m_pendingMessagesToPostToInjectedBundle.append(make_pair(messageName, messageBody));
387 return;
388 }
389
390 // FIXME: We should consider returning false from this function if the messageBody cannot
391 // be encoded.
392 m_process->deprecatedSend(InjectedBundleMessage::PostMessage, 0, CoreIPC::In(messageName, WebContextUserMessageEncoder(messageBody)));
393 }
394
395 // InjectedBundle client
396
didReceiveMessageFromInjectedBundle(const String & messageName,APIObject * messageBody)397 void WebContext::didReceiveMessageFromInjectedBundle(const String& messageName, APIObject* messageBody)
398 {
399 m_injectedBundleClient.didReceiveMessageFromInjectedBundle(this, messageName, messageBody);
400 }
401
didReceiveSynchronousMessageFromInjectedBundle(const String & messageName,APIObject * messageBody,RefPtr<APIObject> & returnData)402 void WebContext::didReceiveSynchronousMessageFromInjectedBundle(const String& messageName, APIObject* messageBody, RefPtr<APIObject>& returnData)
403 {
404 m_injectedBundleClient.didReceiveSynchronousMessageFromInjectedBundle(this, messageName, messageBody, returnData);
405 }
406
407 // HistoryClient
408
didNavigateWithNavigationData(uint64_t pageID,const WebNavigationDataStore & store,uint64_t frameID)409 void WebContext::didNavigateWithNavigationData(uint64_t pageID, const WebNavigationDataStore& store, uint64_t frameID)
410 {
411 WebFrameProxy* frame = m_process->webFrame(frameID);
412 MESSAGE_CHECK(frame);
413 if (!frame->page())
414 return;
415
416 m_historyClient.didNavigateWithNavigationData(this, frame->page(), store, frame);
417 }
418
didPerformClientRedirect(uint64_t pageID,const String & sourceURLString,const String & destinationURLString,uint64_t frameID)419 void WebContext::didPerformClientRedirect(uint64_t pageID, const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
420 {
421 WebFrameProxy* frame = m_process->webFrame(frameID);
422 MESSAGE_CHECK(frame);
423 if (!frame->page())
424 return;
425
426 m_historyClient.didPerformClientRedirect(this, frame->page(), sourceURLString, destinationURLString, frame);
427 }
428
didPerformServerRedirect(uint64_t pageID,const String & sourceURLString,const String & destinationURLString,uint64_t frameID)429 void WebContext::didPerformServerRedirect(uint64_t pageID, const String& sourceURLString, const String& destinationURLString, uint64_t frameID)
430 {
431 WebFrameProxy* frame = m_process->webFrame(frameID);
432 MESSAGE_CHECK(frame);
433 if (!frame->page())
434 return;
435
436 m_historyClient.didPerformServerRedirect(this, frame->page(), sourceURLString, destinationURLString, frame);
437 }
438
didUpdateHistoryTitle(uint64_t pageID,const String & title,const String & url,uint64_t frameID)439 void WebContext::didUpdateHistoryTitle(uint64_t pageID, const String& title, const String& url, uint64_t frameID)
440 {
441 WebFrameProxy* frame = m_process->webFrame(frameID);
442 MESSAGE_CHECK(frame);
443 if (!frame->page())
444 return;
445
446 m_historyClient.didUpdateHistoryTitle(this, frame->page(), title, url, frame);
447 }
448
populateVisitedLinks()449 void WebContext::populateVisitedLinks()
450 {
451 m_historyClient.populateVisitedLinks(this);
452 }
453
statistics()454 WebContext::Statistics& WebContext::statistics()
455 {
456 static Statistics statistics = Statistics();
457
458 return statistics;
459 }
460
setAdditionalPluginsDirectory(const String & directory)461 void WebContext::setAdditionalPluginsDirectory(const String& directory)
462 {
463 Vector<String> directories;
464 directories.append(directory);
465
466 m_pluginInfoStore.setAdditionalPluginsDirectories(directories);
467 }
468
setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)469 void WebContext::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
470 {
471 m_alwaysUsesComplexTextCodePath = alwaysUseComplexText;
472 sendToAllProcesses(Messages::WebProcess::SetAlwaysUsesComplexTextCodePath(alwaysUseComplexText));
473 }
474
registerURLSchemeAsEmptyDocument(const String & urlScheme)475 void WebContext::registerURLSchemeAsEmptyDocument(const String& urlScheme)
476 {
477 m_schemesToRegisterAsEmptyDocument.add(urlScheme);
478 sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsEmptyDocument(urlScheme));
479 }
480
registerURLSchemeAsSecure(const String & urlScheme)481 void WebContext::registerURLSchemeAsSecure(const String& urlScheme)
482 {
483 m_schemesToRegisterAsSecure.add(urlScheme);
484 sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsSecure(urlScheme));
485 }
486
setDomainRelaxationForbiddenForURLScheme(const String & urlScheme)487 void WebContext::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme)
488 {
489 m_schemesToSetDomainRelaxationForbiddenFor.add(urlScheme);
490 sendToAllProcesses(Messages::WebProcess::SetDomainRelaxationForbiddenForURLScheme(urlScheme));
491 }
492
setCacheModel(CacheModel cacheModel)493 void WebContext::setCacheModel(CacheModel cacheModel)
494 {
495 m_cacheModel = cacheModel;
496 sendToAllProcesses(Messages::WebProcess::SetCacheModel(static_cast<uint32_t>(m_cacheModel)));
497 }
498
setDefaultRequestTimeoutInterval(double timeoutInterval)499 void WebContext::setDefaultRequestTimeoutInterval(double timeoutInterval)
500 {
501 sendToAllProcesses(Messages::WebProcess::SetDefaultRequestTimeoutInterval(timeoutInterval));
502 }
503
addVisitedLink(const String & visitedURL)504 void WebContext::addVisitedLink(const String& visitedURL)
505 {
506 if (visitedURL.isEmpty())
507 return;
508
509 LinkHash linkHash = visitedLinkHash(visitedURL.characters(), visitedURL.length());
510 addVisitedLinkHash(linkHash);
511 }
512
addVisitedLinkHash(LinkHash linkHash)513 void WebContext::addVisitedLinkHash(LinkHash linkHash)
514 {
515 m_visitedLinkProvider.addVisitedLink(linkHash);
516 }
517
getPlugins(bool refresh,Vector<PluginInfo> & plugins)518 void WebContext::getPlugins(bool refresh, Vector<PluginInfo>& plugins)
519 {
520 if (refresh)
521 pluginInfoStore()->refresh();
522 pluginInfoStore()->getPlugins(plugins);
523 }
524
getPluginPath(const String & mimeType,const String & urlString,String & pluginPath)525 void WebContext::getPluginPath(const String& mimeType, const String& urlString, String& pluginPath)
526 {
527 String newMimeType = mimeType.lower();
528
529 PluginInfoStore::Plugin plugin = pluginInfoStore()->findPlugin(newMimeType, KURL(ParsedURLString, urlString));
530 if (!plugin.path)
531 return;
532
533 pluginPath = plugin.path;
534 }
535
536 #if !ENABLE(PLUGIN_PROCESS)
didGetSitesWithPluginData(const Vector<String> & sites,uint64_t callbackID)537 void WebContext::didGetSitesWithPluginData(const Vector<String>& sites, uint64_t callbackID)
538 {
539 m_pluginSiteDataManager->didGetSitesWithData(sites, callbackID);
540 }
541
didClearPluginSiteData(uint64_t callbackID)542 void WebContext::didClearPluginSiteData(uint64_t callbackID)
543 {
544 m_pluginSiteDataManager->didClearSiteData(callbackID);
545 }
546 #endif
547
createDownloadProxy()548 DownloadProxy* WebContext::createDownloadProxy()
549 {
550 RefPtr<DownloadProxy> downloadProxy = DownloadProxy::create(this);
551 m_downloads.set(downloadProxy->downloadID(), downloadProxy);
552 return downloadProxy.get();
553 }
554
downloadFinished(DownloadProxy * downloadProxy)555 void WebContext::downloadFinished(DownloadProxy* downloadProxy)
556 {
557 ASSERT(m_downloads.contains(downloadProxy->downloadID()));
558
559 downloadProxy->invalidate();
560 m_downloads.remove(downloadProxy->downloadID());
561 }
562
563 // FIXME: This is not the ideal place for this function.
pdfAndPostScriptMIMETypes()564 HashSet<String, CaseFoldingHash> WebContext::pdfAndPostScriptMIMETypes()
565 {
566 HashSet<String, CaseFoldingHash> mimeTypes;
567
568 mimeTypes.add("application/pdf");
569 mimeTypes.add("application/postscript");
570 mimeTypes.add("text/pdf");
571
572 return mimeTypes;
573 }
574
didReceiveMessage(CoreIPC::Connection * connection,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments)575 void WebContext::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
576 {
577 if (messageID.is<CoreIPC::MessageClassWebContext>()) {
578 didReceiveWebContextMessage(connection, messageID, arguments);
579 return;
580 }
581
582 if (messageID.is<CoreIPC::MessageClassDownloadProxy>()) {
583 if (DownloadProxy* downloadProxy = m_downloads.get(arguments->destinationID()).get())
584 downloadProxy->didReceiveDownloadProxyMessage(connection, messageID, arguments);
585
586 return;
587 }
588
589 if (messageID.is<CoreIPC::MessageClassWebApplicationCacheManagerProxy>()) {
590 m_applicationCacheManagerProxy->didReceiveMessage(connection, messageID, arguments);
591 return;
592 }
593
594 if (messageID.is<CoreIPC::MessageClassWebCookieManagerProxy>()) {
595 m_cookieManagerProxy->didReceiveMessage(connection, messageID, arguments);
596 return;
597 }
598
599 if (messageID.is<CoreIPC::MessageClassWebDatabaseManagerProxy>()) {
600 m_databaseManagerProxy->didReceiveWebDatabaseManagerProxyMessage(connection, messageID, arguments);
601 return;
602 }
603
604 if (messageID.is<CoreIPC::MessageClassWebGeolocationManagerProxy>()) {
605 m_geolocationManagerProxy->didReceiveMessage(connection, messageID, arguments);
606 return;
607 }
608
609 if (messageID.is<CoreIPC::MessageClassWebIconDatabase>()) {
610 m_iconDatabase->didReceiveMessage(connection, messageID, arguments);
611 return;
612 }
613
614 if (messageID.is<CoreIPC::MessageClassWebKeyValueStorageManagerProxy>()) {
615 m_keyValueStorageManagerProxy->didReceiveMessage(connection, messageID, arguments);
616 return;
617 }
618
619 if (messageID.is<CoreIPC::MessageClassWebMediaCacheManagerProxy>()) {
620 m_mediaCacheManagerProxy->didReceiveMessage(connection, messageID, arguments);
621 return;
622 }
623
624 if (messageID.is<CoreIPC::MessageClassWebResourceCacheManagerProxy>()) {
625 m_resourceCacheManagerProxy->didReceiveWebResourceCacheManagerProxyMessage(connection, messageID, arguments);
626 return;
627 }
628
629 switch (messageID.get<WebContextLegacyMessage::Kind>()) {
630 case WebContextLegacyMessage::PostMessage: {
631 String messageName;
632 RefPtr<APIObject> messageBody;
633 WebContextUserMessageDecoder messageDecoder(messageBody, this);
634 if (!arguments->decode(CoreIPC::Out(messageName, messageDecoder)))
635 return;
636
637 didReceiveMessageFromInjectedBundle(messageName, messageBody.get());
638 return;
639 }
640 case WebContextLegacyMessage::PostSynchronousMessage:
641 ASSERT_NOT_REACHED();
642 }
643
644 ASSERT_NOT_REACHED();
645 }
646
didReceiveSyncMessage(CoreIPC::Connection * connection,CoreIPC::MessageID messageID,CoreIPC::ArgumentDecoder * arguments,CoreIPC::ArgumentEncoder * reply)647 CoreIPC::SyncReplyMode WebContext::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, CoreIPC::ArgumentEncoder* reply)
648 {
649 if (messageID.is<CoreIPC::MessageClassWebContext>())
650 return didReceiveSyncWebContextMessage(connection, messageID, arguments, reply);
651
652 if (messageID.is<CoreIPC::MessageClassDownloadProxy>()) {
653 if (DownloadProxy* downloadProxy = m_downloads.get(arguments->destinationID()).get())
654 return downloadProxy->didReceiveSyncDownloadProxyMessage(connection, messageID, arguments, reply);
655
656 return CoreIPC::AutomaticReply;
657 }
658
659 if (messageID.is<CoreIPC::MessageClassWebIconDatabase>())
660 return m_iconDatabase->didReceiveSyncMessage(connection, messageID, arguments, reply);
661
662 switch (messageID.get<WebContextLegacyMessage::Kind>()) {
663 case WebContextLegacyMessage::PostSynchronousMessage: {
664 // FIXME: We should probably encode something in the case that the arguments do not decode correctly.
665
666 String messageName;
667 RefPtr<APIObject> messageBody;
668 WebContextUserMessageDecoder messageDecoder(messageBody, this);
669 if (!arguments->decode(CoreIPC::Out(messageName, messageDecoder)))
670 return CoreIPC::AutomaticReply;
671
672 RefPtr<APIObject> returnData;
673 didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody.get(), returnData);
674 reply->encode(CoreIPC::In(WebContextUserMessageEncoder(returnData.get())));
675 return CoreIPC::AutomaticReply;
676 }
677 case WebContextLegacyMessage::PostMessage:
678 ASSERT_NOT_REACHED();
679 }
680
681 return CoreIPC::AutomaticReply;
682 }
683
setEnhancedAccessibility(bool flag)684 void WebContext::setEnhancedAccessibility(bool flag)
685 {
686 sendToAllProcesses(Messages::WebProcess::SetEnhancedAccessibility(flag));
687 }
688
startMemorySampler(const double interval)689 void WebContext::startMemorySampler(const double interval)
690 {
691 // For new WebProcesses we will also want to start the Memory Sampler
692 m_memorySamplerEnabled = true;
693 m_memorySamplerInterval = interval;
694
695 // For UIProcess
696 #if ENABLE(MEMORY_SAMPLER)
697 WebMemorySampler::shared()->start(interval);
698 #endif
699
700 // For WebProcess
701 SandboxExtension::Handle sampleLogSandboxHandle;
702 double now = WTF::currentTime();
703 String sampleLogFilePath = String::format("WebProcess%llu", static_cast<uint64_t>(now));
704 sampleLogFilePath = SandboxExtension::createHandleForTemporaryFile(sampleLogFilePath, SandboxExtension::WriteOnly, sampleLogSandboxHandle);
705
706 sendToAllProcesses(Messages::WebProcess::StartMemorySampler(sampleLogSandboxHandle, sampleLogFilePath, interval));
707 }
708
stopMemorySampler()709 void WebContext::stopMemorySampler()
710 {
711 // For WebProcess
712 m_memorySamplerEnabled = false;
713
714 // For UIProcess
715 #if ENABLE(MEMORY_SAMPLER)
716 WebMemorySampler::shared()->stop();
717 #endif
718
719 sendToAllProcesses(Messages::WebProcess::StopMemorySampler());
720 }
721
databaseDirectory() const722 String WebContext::databaseDirectory() const
723 {
724 if (!m_overrideDatabaseDirectory.isEmpty())
725 return m_overrideDatabaseDirectory;
726
727 return platformDefaultDatabaseDirectory();
728 }
729
setIconDatabasePath(const String & path)730 void WebContext::setIconDatabasePath(const String& path)
731 {
732 m_overrideIconDatabasePath = path;
733 m_iconDatabase->setDatabasePath(path);
734 }
735
iconDatabasePath() const736 String WebContext::iconDatabasePath() const
737 {
738 if (!m_overrideIconDatabasePath.isEmpty())
739 return m_overrideIconDatabasePath;
740
741 return platformDefaultIconDatabasePath();
742 }
743
localStorageDirectory() const744 String WebContext::localStorageDirectory() const
745 {
746 if (!m_overrideLocalStorageDirectory.isEmpty())
747 return m_overrideLocalStorageDirectory;
748
749 return platformDefaultLocalStorageDirectory();
750 }
751
setHTTPPipeliningEnabled(bool enabled)752 void WebContext::setHTTPPipeliningEnabled(bool enabled)
753 {
754 #if PLATFORM(MAC)
755 ResourceRequest::setHTTPPipeliningEnabled(enabled);
756 #endif
757 }
758
httpPipeliningEnabled()759 bool WebContext::httpPipeliningEnabled()
760 {
761 #if PLATFORM(MAC)
762 return ResourceRequest::httpPipeliningEnabled();
763 #else
764 return false;
765 #endif
766 }
767
768 } // namespace WebKit
769