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 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 82 WebContext* WebContext::sharedThreadContext() 83 { 84 RunLoop::initializeMainRunLoop(); 85 static WebContext* context = adoptRef(new WebContext(ProcessModelSharedSecondaryThread, String())).leakRef(); 86 return context; 87 } 88 89 PassRefPtr<WebContext> WebContext::create(const String& injectedBundlePath) 90 { 91 WTF::initializeMainThread(); 92 RunLoop::initializeMainRunLoop(); 93 return adoptRef(new WebContext(ProcessModelSecondaryProcess, injectedBundlePath)); 94 } 95 96 static Vector<WebContext*>& contexts() 97 { 98 DEFINE_STATIC_LOCAL(Vector<WebContext*>, contexts, ()); 99 100 return contexts; 101 } 102 103 const Vector<WebContext*>& WebContext::allContexts() 104 { 105 return contexts(); 106 } 107 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 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 188 void WebContext::initializeInjectedBundleClient(const WKContextInjectedBundleClient* client) 189 { 190 m_injectedBundleClient.initialize(client); 191 } 192 193 void WebContext::initializeHistoryClient(const WKContextHistoryClient* client) 194 { 195 m_historyClient.initialize(client); 196 197 sendToAllProcesses(Messages::WebProcess::SetShouldTrackVisitedLinks(m_historyClient.shouldTrackVisitedLinks())); 198 } 199 200 void WebContext::initializeDownloadClient(const WKContextDownloadClient* client) 201 { 202 m_downloadClient.initialize(client); 203 } 204 205 void WebContext::languageChanged(void* context) 206 { 207 static_cast<WebContext*>(context)->languageChanged(); 208 } 209 210 void WebContext::languageChanged() 211 { 212 sendToAllProcesses(Messages::WebProcess::LanguageChanged(defaultLanguage())); 213 } 214 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 266 void WebContext::enableProcessTermination() 267 { 268 m_processTerminationEnabled = true; 269 if (shouldTerminate(m_process.get())) 270 m_process->terminate(); 271 } 272 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 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 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 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 364 WebProcessProxy* WebContext::relaunchProcessIfNecessary() 365 { 366 ensureWebProcess(); 367 368 ASSERT(m_process); 369 return m_process.get(); 370 } 371 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 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 395 void WebContext::didReceiveMessageFromInjectedBundle(const String& messageName, APIObject* messageBody) 396 { 397 m_injectedBundleClient.didReceiveMessageFromInjectedBundle(this, messageName, messageBody); 398 } 399 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 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 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 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 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 447 void WebContext::populateVisitedLinks() 448 { 449 m_historyClient.populateVisitedLinks(this); 450 } 451 452 WebContext::Statistics& WebContext::statistics() 453 { 454 static Statistics statistics = Statistics(); 455 456 return statistics; 457 } 458 459 void WebContext::setAdditionalPluginsDirectory(const String& directory) 460 { 461 Vector<String> directories; 462 directories.append(directory); 463 464 m_pluginInfoStore.setAdditionalPluginsDirectories(directories); 465 } 466 467 void WebContext::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText) 468 { 469 m_alwaysUsesComplexTextCodePath = alwaysUseComplexText; 470 sendToAllProcesses(Messages::WebProcess::SetAlwaysUsesComplexTextCodePath(alwaysUseComplexText)); 471 } 472 473 void WebContext::registerURLSchemeAsEmptyDocument(const String& urlScheme) 474 { 475 m_schemesToRegisterAsEmptyDocument.add(urlScheme); 476 sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsEmptyDocument(urlScheme)); 477 } 478 479 void WebContext::registerURLSchemeAsSecure(const String& urlScheme) 480 { 481 m_schemesToRegisterAsSecure.add(urlScheme); 482 sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsSecure(urlScheme)); 483 } 484 485 void WebContext::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) 486 { 487 m_schemesToSetDomainRelaxationForbiddenFor.add(urlScheme); 488 sendToAllProcesses(Messages::WebProcess::SetDomainRelaxationForbiddenForURLScheme(urlScheme)); 489 } 490 491 void WebContext::setCacheModel(CacheModel cacheModel) 492 { 493 m_cacheModel = cacheModel; 494 sendToAllProcesses(Messages::WebProcess::SetCacheModel(static_cast<uint32_t>(m_cacheModel))); 495 } 496 497 void WebContext::setDefaultRequestTimeoutInterval(double timeoutInterval) 498 { 499 sendToAllProcesses(Messages::WebProcess::SetDefaultRequestTimeoutInterval(timeoutInterval)); 500 } 501 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 511 void WebContext::addVisitedLinkHash(LinkHash linkHash) 512 { 513 m_visitedLinkProvider.addVisitedLink(linkHash); 514 } 515 516 void WebContext::getPlugins(bool refresh, Vector<PluginInfo>& plugins) 517 { 518 if (refresh) 519 pluginInfoStore()->refresh(); 520 pluginInfoStore()->getPlugins(plugins); 521 } 522 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) 535 void WebContext::didGetSitesWithPluginData(const Vector<String>& sites, uint64_t callbackID) 536 { 537 m_pluginSiteDataManager->didGetSitesWithData(sites, callbackID); 538 } 539 540 void WebContext::didClearPluginSiteData(uint64_t callbackID) 541 { 542 m_pluginSiteDataManager->didClearSiteData(callbackID); 543 } 544 #endif 545 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 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. 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 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 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 682 void WebContext::setEnhancedAccessibility(bool flag) 683 { 684 sendToAllProcesses(Messages::WebProcess::SetEnhancedAccessibility(flag)); 685 } 686 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 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 720 String WebContext::databaseDirectory() const 721 { 722 if (!m_overrideDatabaseDirectory.isEmpty()) 723 return m_overrideDatabaseDirectory; 724 725 return platformDefaultDatabaseDirectory(); 726 } 727 728 void WebContext::setIconDatabasePath(const String& path) 729 { 730 m_overrideIconDatabasePath = path; 731 m_iconDatabase->setDatabasePath(path); 732 } 733 734 String WebContext::iconDatabasePath() const 735 { 736 if (!m_overrideIconDatabasePath.isEmpty()) 737 return m_overrideIconDatabasePath; 738 739 return platformDefaultIconDatabasePath(); 740 } 741 742 String WebContext::localStorageDirectory() const 743 { 744 if (!m_overrideLocalStorageDirectory.isEmpty()) 745 return m_overrideLocalStorageDirectory; 746 747 return platformDefaultLocalStorageDirectory(); 748 } 749 750 void WebContext::setHTTPPipeliningEnabled(bool enabled) 751 { 752 #if PLATFORM(MAC) 753 ResourceRequest::setHTTPPipeliningEnabled(enabled); 754 #endif 755 } 756 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