1/* 2 * Copyright (C) 2009, 2010, 2012 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 "WebProcess.h" 28 29#include "AuthenticationManager.h" 30#include "EventDispatcher.h" 31#include "InjectedBundle.h" 32#include "InjectedBundleUserMessageCoders.h" 33#include "Logging.h" 34#include "PluginProcessConnectionManager.h" 35#include "StatisticsData.h" 36#include "WebApplicationCacheManager.h" 37#include "WebConnectionToUIProcess.h" 38#include "WebContextMessages.h" 39#include "WebCookieManager.h" 40#include "WebCoreArgumentCoders.h" 41#include "WebFrame.h" 42#include "WebFrameNetworkingContext.h" 43#include "WebGeolocationManager.h" 44#include "WebIconDatabaseProxy.h" 45#include "WebMediaCacheManager.h" 46#include "WebMemorySampler.h" 47#include "WebPage.h" 48#include "WebPageCreationParameters.h" 49#include "WebPageGroupProxyMessages.h" 50#include "WebPlatformStrategies.h" 51#include "WebPreferencesStore.h" 52#include "WebProcessCreationParameters.h" 53#include "WebProcessMessages.h" 54#include "WebProcessProxyMessages.h" 55#include "WebResourceCacheManager.h" 56#include <JavaScriptCore/JSLock.h> 57#include <JavaScriptCore/MemoryStatistics.h> 58#include <WebCore/AXObjectCache.h> 59#include <WebCore/ApplicationCacheStorage.h> 60#include <WebCore/AuthenticationChallenge.h> 61#include <WebCore/CrossOriginPreflightResultCache.h> 62#include <WebCore/Font.h> 63#include <WebCore/FontCache.h> 64#include <WebCore/Frame.h> 65#include <WebCore/FrameLoader.h> 66#include <WebCore/GCController.h> 67#include <WebCore/GlyphPageTreeNode.h> 68#include <WebCore/IconDatabase.h> 69#include <WebCore/JSDOMWindow.h> 70#include <WebCore/Language.h> 71#include <WebCore/MemoryCache.h> 72#include <WebCore/MemoryPressureHandler.h> 73#include <WebCore/Page.h> 74#include <WebCore/PageCache.h> 75#include <WebCore/PageGroup.h> 76#include <WebCore/ResourceHandle.h> 77#include <WebCore/RunLoop.h> 78#include <WebCore/SchemeRegistry.h> 79#include <WebCore/SecurityOrigin.h> 80#include <WebCore/Settings.h> 81#include <WebCore/StorageTracker.h> 82#include <wtf/CurrentTime.h> 83#include <wtf/HashCountedSet.h> 84#include <wtf/PassRefPtr.h> 85#include <wtf/text/StringHash.h> 86 87#if ENABLE(NETWORK_INFO) 88#include "WebNetworkInfoManager.h" 89#include "WebNetworkInfoManagerMessages.h" 90#endif 91 92#if ENABLE(NETWORK_PROCESS) 93#include "CookieStorageShim.h" 94#include "NetworkProcessConnection.h" 95#endif 96 97#if !OS(WINDOWS) 98#include <unistd.h> 99#endif 100 101#if !ENABLE(PLUGIN_PROCESS) 102#include "NetscapePluginModule.h" 103#endif 104 105#if ENABLE(CUSTOM_PROTOCOLS) 106#include "CustomProtocolManager.h" 107#endif 108 109#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) 110#include "WebNotificationManager.h" 111#endif 112 113#if ENABLE(SQL_DATABASE) 114#include "WebDatabaseManager.h" 115#endif 116 117#if ENABLE(BATTERY_STATUS) 118#include "WebBatteryManager.h" 119#endif 120 121#if ENABLE(NETWORK_PROCESS) 122#include "WebResourceLoadScheduler.h" 123#endif 124 125#if ENABLE(PLUGIN_PROCESS) 126#include "PluginProcessConnectionManager.h" 127#endif 128 129#if USE(SECURITY_FRAMEWORK) 130#include "SecItemShim.h" 131#endif 132 133#if USE(SOUP) 134#include "WebSoupRequestManager.h" 135#endif 136 137using namespace JSC; 138using namespace WebCore; 139 140// This should be less than plugInAutoStartExpirationTimeThreshold in PlugInAutoStartProvider. 141static const double plugInAutoStartExpirationTimeUpdateThreshold = 29 * 24 * 60 * 60; 142 143// This should be greater than tileRevalidationTimeout in TileController. 144static const double nonVisibleProcessCleanupDelay = 10; 145 146namespace WebKit { 147 148WebProcess& WebProcess::shared() 149{ 150 static WebProcess& process = *new WebProcess; 151 return process; 152} 153 154WebProcess::WebProcess() 155 : m_eventDispatcher(EventDispatcher::create()) 156 , m_inDidClose(false) 157 , m_shouldTrackVisitedLinks(true) 158 , m_hasSetCacheModel(false) 159 , m_cacheModel(CacheModelDocumentViewer) 160#if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC) 161 , m_compositingRenderServerPort(MACH_PORT_NULL) 162#endif 163#if PLATFORM(MAC) 164 , m_clearResourceCachesDispatchGroup(0) 165#endif 166 , m_fullKeyboardAccessEnabled(false) 167#if PLATFORM(QT) 168 , m_networkAccessManager(0) 169#endif 170 , m_textCheckerState() 171 , m_iconDatabaseProxy(new WebIconDatabaseProxy(this)) 172#if ENABLE(NETWORK_PROCESS) 173 , m_usesNetworkProcess(false) 174 , m_webResourceLoadScheduler(new WebResourceLoadScheduler) 175#endif 176#if ENABLE(PLUGIN_PROCESS) 177 , m_pluginProcessConnectionManager(PluginProcessConnectionManager::create()) 178#endif 179 , m_nonVisibleProcessCleanupTimer(this, &WebProcess::nonVisibleProcessCleanupTimerFired) 180{ 181 // Initialize our platform strategies. 182 WebPlatformStrategies::initialize(); 183 184 // FIXME: This should moved to where WebProcess::initialize is called, 185 // so that ports have a chance to customize, and ifdefs in this file are 186 // limited. 187 addSupplement<WebGeolocationManager>(); 188 addSupplement<WebApplicationCacheManager>(); 189 addSupplement<WebResourceCacheManager>(); 190 addSupplement<WebCookieManager>(); 191 addSupplement<WebMediaCacheManager>(); 192 addSupplement<AuthenticationManager>(); 193 194#if ENABLE(SQL_DATABASE) 195 addSupplement<WebDatabaseManager>(); 196#endif 197#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) 198 addSupplement<WebNotificationManager>(); 199#endif 200#if ENABLE(CUSTOM_PROTOCOLS) 201 addSupplement<CustomProtocolManager>(); 202#endif 203#if ENABLE(BATTERY_STATUS) 204 addSupplement<WebBatteryManager>(); 205#endif 206#if ENABLE(NETWORK_INFO) 207 addSupplement<WebNetworkInfoManager>(); 208#endif 209#if USE(SOUP) 210 addSupplement<WebSoupRequestManager>(); 211#endif 212} 213 214void WebProcess::initializeProcess(const ChildProcessInitializationParameters& parameters) 215{ 216 platformInitializeProcess(parameters); 217} 218 219void WebProcess::initializeConnection(CoreIPC::Connection* connection) 220{ 221 ChildProcess::initializeConnection(connection); 222 223 connection->setShouldExitOnSyncMessageSendFailure(true); 224 225 m_eventDispatcher->initializeConnection(connection); 226 227#if ENABLE(PLUGIN_PROCESS) 228 m_pluginProcessConnectionManager->initializeConnection(connection); 229#endif 230 231#if USE(SECURITY_FRAMEWORK) 232 SecItemShim::shared().initializeConnection(connection); 233#endif 234 235 WebProcessSupplementMap::const_iterator it = m_supplements.begin(); 236 WebProcessSupplementMap::const_iterator end = m_supplements.end(); 237 for (; it != end; ++it) 238 it->value->initializeConnection(connection); 239 240 m_webConnection = WebConnectionToUIProcess::create(this); 241 242 // In order to ensure that the asynchronous messages that are used for notifying the UI process 243 // about when WebFrame objects come and go are always delivered before the synchronous policy messages, 244 // use this flag to force synchronous messages to be treated as asynchronous messages in the UI process 245 // unless when doing so would lead to a deadlock. 246 connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true); 247} 248 249void WebProcess::didCreateDownload() 250{ 251 disableTermination(); 252} 253 254void WebProcess::didDestroyDownload() 255{ 256 enableTermination(); 257} 258 259CoreIPC::Connection* WebProcess::downloadProxyConnection() 260{ 261 return parentProcessConnection(); 262} 263 264AuthenticationManager& WebProcess::downloadsAuthenticationManager() 265{ 266 return *supplement<AuthenticationManager>(); 267} 268 269void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::MessageDecoder& decoder) 270{ 271 ASSERT(m_pageMap.isEmpty()); 272 273 platformInitializeWebProcess(parameters, decoder); 274 275 memoryPressureHandler().install(); 276 277 RefPtr<APIObject> injectedBundleInitializationUserData; 278 InjectedBundleUserMessageDecoder messageDecoder(injectedBundleInitializationUserData); 279 if (!decoder.decode(messageDecoder)) 280 return; 281 282 if (!parameters.injectedBundlePath.isEmpty()) { 283 m_injectedBundle = InjectedBundle::create(parameters.injectedBundlePath); 284 m_injectedBundle->setSandboxExtension(SandboxExtension::create(parameters.injectedBundlePathExtensionHandle)); 285 286 if (!m_injectedBundle->load(injectedBundleInitializationUserData.get())) { 287 // Don't keep around the InjectedBundle reference if the load fails. 288 m_injectedBundle.clear(); 289 } 290 } 291 292 WebProcessSupplementMap::const_iterator it = m_supplements.begin(); 293 WebProcessSupplementMap::const_iterator end = m_supplements.end(); 294 for (; it != end; ++it) 295 it->value->initialize(parameters); 296 297#if ENABLE(ICONDATABASE) 298 m_iconDatabaseProxy->setEnabled(parameters.iconDatabaseEnabled); 299#endif 300 301 if (!parameters.applicationCacheDirectory.isEmpty()) 302 cacheStorage().setCacheDirectory(parameters.applicationCacheDirectory); 303 304 setShouldTrackVisitedLinks(parameters.shouldTrackVisitedLinks); 305 setCacheModel(static_cast<uint32_t>(parameters.cacheModel)); 306 307 if (!parameters.languages.isEmpty()) 308 overrideUserPreferredLanguages(parameters.languages); 309 310 m_textCheckerState = parameters.textCheckerState; 311 312 m_fullKeyboardAccessEnabled = parameters.fullKeyboardAccessEnabled; 313 314 for (size_t i = 0; i < parameters.urlSchemesRegistererdAsEmptyDocument.size(); ++i) 315 registerURLSchemeAsEmptyDocument(parameters.urlSchemesRegistererdAsEmptyDocument[i]); 316 317 for (size_t i = 0; i < parameters.urlSchemesRegisteredAsSecure.size(); ++i) 318 registerURLSchemeAsSecure(parameters.urlSchemesRegisteredAsSecure[i]); 319 320 for (size_t i = 0; i < parameters.urlSchemesForWhichDomainRelaxationIsForbidden.size(); ++i) 321 setDomainRelaxationForbiddenForURLScheme(parameters.urlSchemesForWhichDomainRelaxationIsForbidden[i]); 322 323 for (size_t i = 0; i < parameters.urlSchemesRegisteredAsLocal.size(); ++i) 324 registerURLSchemeAsLocal(parameters.urlSchemesRegisteredAsLocal[i]); 325 326 for (size_t i = 0; i < parameters.urlSchemesRegisteredAsNoAccess.size(); ++i) 327 registerURLSchemeAsNoAccess(parameters.urlSchemesRegisteredAsNoAccess[i]); 328 329 for (size_t i = 0; i < parameters.urlSchemesRegisteredAsDisplayIsolated.size(); ++i) 330 registerURLSchemeAsDisplayIsolated(parameters.urlSchemesRegisteredAsDisplayIsolated[i]); 331 332 for (size_t i = 0; i < parameters.urlSchemesRegisteredAsCORSEnabled.size(); ++i) 333 registerURLSchemeAsCORSEnabled(parameters.urlSchemesRegisteredAsCORSEnabled[i]); 334 335 setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval); 336 337 if (parameters.shouldAlwaysUseComplexTextCodePath) 338 setAlwaysUsesComplexTextCodePath(true); 339 340 if (parameters.shouldUseFontSmoothing) 341 setShouldUseFontSmoothing(true); 342 343#if PLATFORM(MAC) || USE(CFNETWORK) 344 WebFrameNetworkingContext::setPrivateBrowsingStorageSessionIdentifierBase(parameters.uiProcessBundleIdentifier); 345#endif 346 347#if ENABLE(NETWORK_PROCESS) 348 m_usesNetworkProcess = parameters.usesNetworkProcess; 349 ensureNetworkProcessConnection(); 350 351 if (usesNetworkProcess()) 352 CookieStorageShim::shared().initialize(); 353#endif 354 setTerminationTimeout(parameters.terminationTimeout); 355 356 resetPlugInAutoStartOriginHashes(parameters.plugInAutoStartOriginHashes); 357 for (size_t i = 0; i < parameters.plugInAutoStartOrigins.size(); ++i) 358 m_plugInAutoStartOrigins.add(parameters.plugInAutoStartOrigins[i]); 359 360 setMemoryCacheDisabled(parameters.memoryCacheDisabled); 361} 362 363#if ENABLE(NETWORK_PROCESS) 364void WebProcess::ensureNetworkProcessConnection() 365{ 366 if (!m_usesNetworkProcess) 367 return; 368 369 if (m_networkProcessConnection) 370 return; 371 372 CoreIPC::Attachment encodedConnectionIdentifier; 373 374 if (!parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetNetworkProcessConnection(), 375 Messages::WebProcessProxy::GetNetworkProcessConnection::Reply(encodedConnectionIdentifier), 0)) 376 return; 377 378#if PLATFORM(MAC) 379 CoreIPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port()); 380 if (CoreIPC::Connection::identifierIsNull(connectionIdentifier)) 381 return; 382#else 383 ASSERT_NOT_REACHED(); 384#endif 385 m_networkProcessConnection = NetworkProcessConnection::create(connectionIdentifier); 386} 387#endif // ENABLE(NETWORK_PROCESS) 388 389void WebProcess::setShouldTrackVisitedLinks(bool shouldTrackVisitedLinks) 390{ 391 m_shouldTrackVisitedLinks = shouldTrackVisitedLinks; 392 PageGroup::setShouldTrackVisitedLinks(shouldTrackVisitedLinks); 393} 394 395void WebProcess::registerURLSchemeAsEmptyDocument(const String& urlScheme) 396{ 397 SchemeRegistry::registerURLSchemeAsEmptyDocument(urlScheme); 398} 399 400void WebProcess::registerURLSchemeAsSecure(const String& urlScheme) const 401{ 402 SchemeRegistry::registerURLSchemeAsSecure(urlScheme); 403} 404 405void WebProcess::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) const 406{ 407 SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(true, urlScheme); 408} 409 410void WebProcess::registerURLSchemeAsLocal(const String& urlScheme) const 411{ 412 SchemeRegistry::registerURLSchemeAsLocal(urlScheme); 413} 414 415void WebProcess::registerURLSchemeAsNoAccess(const String& urlScheme) const 416{ 417 SchemeRegistry::registerURLSchemeAsNoAccess(urlScheme); 418} 419 420void WebProcess::registerURLSchemeAsDisplayIsolated(const String& urlScheme) const 421{ 422 SchemeRegistry::registerURLSchemeAsDisplayIsolated(urlScheme); 423} 424 425void WebProcess::registerURLSchemeAsCORSEnabled(const String& urlScheme) const 426{ 427 SchemeRegistry::registerURLSchemeAsCORSEnabled(urlScheme); 428} 429 430void WebProcess::setDefaultRequestTimeoutInterval(double timeoutInterval) 431{ 432 ResourceRequest::setDefaultTimeoutInterval(timeoutInterval); 433} 434 435void WebProcess::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText) 436{ 437 WebCore::Font::setCodePath(alwaysUseComplexText ? WebCore::Font::Complex : WebCore::Font::Auto); 438} 439 440void WebProcess::setShouldUseFontSmoothing(bool useFontSmoothing) 441{ 442 WebCore::Font::setShouldUseSmoothing(useFontSmoothing); 443} 444 445void WebProcess::userPreferredLanguagesChanged(const Vector<String>& languages) const 446{ 447 overrideUserPreferredLanguages(languages); 448 languageDidChange(); 449} 450 451void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled) 452{ 453 m_fullKeyboardAccessEnabled = fullKeyboardAccessEnabled; 454} 455 456void WebProcess::ensurePrivateBrowsingSession() 457{ 458#if PLATFORM(MAC) || USE(CFNETWORK) 459 WebFrameNetworkingContext::ensurePrivateBrowsingSession(); 460#endif 461} 462 463void WebProcess::destroyPrivateBrowsingSession() 464{ 465#if PLATFORM(MAC) || USE(CFNETWORK) 466 WebFrameNetworkingContext::destroyPrivateBrowsingSession(); 467#endif 468} 469 470DownloadManager& WebProcess::downloadManager() 471{ 472#if ENABLE(NETWORK_PROCESS) 473 ASSERT(!m_usesNetworkProcess); 474#endif 475 476 DEFINE_STATIC_LOCAL(DownloadManager, downloadManager, (this)); 477 return downloadManager; 478} 479 480#if ENABLE(PLUGIN_PROCESS) 481PluginProcessConnectionManager& WebProcess::pluginProcessConnectionManager() 482{ 483 return *m_pluginProcessConnectionManager; 484} 485#endif 486 487void WebProcess::setVisitedLinkTable(const SharedMemory::Handle& handle) 488{ 489 RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly); 490 if (!sharedMemory) 491 return; 492 493 m_visitedLinkTable.setSharedMemory(sharedMemory.release()); 494} 495 496void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes) 497{ 498 // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext. 499 for (size_t i = 0; i < linkHashes.size(); ++i) { 500 HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator it = m_pageGroupMap.begin(); 501 HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator end = m_pageGroupMap.end(); 502 for (; it != end; ++it) 503 Page::visitedStateChanged(PageGroup::pageGroup(it->value->identifier()), linkHashes[i]); 504 } 505 506 pageCache()->markPagesForVistedLinkStyleRecalc(); 507} 508 509void WebProcess::allVisitedLinkStateChanged() 510{ 511 // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext. 512 HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator it = m_pageGroupMap.begin(); 513 HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator end = m_pageGroupMap.end(); 514 for (; it != end; ++it) 515 Page::allVisitedStateChanged(PageGroup::pageGroup(it->value->identifier())); 516 517 pageCache()->markPagesForVistedLinkStyleRecalc(); 518} 519 520bool WebProcess::isLinkVisited(LinkHash linkHash) const 521{ 522 return m_visitedLinkTable.isLinkVisited(linkHash); 523} 524 525void WebProcess::addVisitedLink(WebCore::LinkHash linkHash) 526{ 527 if (isLinkVisited(linkHash) || !m_shouldTrackVisitedLinks) 528 return; 529 parentProcessConnection()->send(Messages::WebContext::AddVisitedLinkHash(linkHash), 0); 530} 531 532void WebProcess::setCacheModel(uint32_t cm) 533{ 534 CacheModel cacheModel = static_cast<CacheModel>(cm); 535 536 if (!m_hasSetCacheModel || cacheModel != m_cacheModel) { 537 m_hasSetCacheModel = true; 538 m_cacheModel = cacheModel; 539 platformSetCacheModel(cacheModel); 540 } 541} 542 543WebPage* WebProcess::focusedWebPage() const 544{ 545 HashMap<uint64_t, RefPtr<WebPage>>::const_iterator end = m_pageMap.end(); 546 for (HashMap<uint64_t, RefPtr<WebPage>>::const_iterator it = m_pageMap.begin(); it != end; ++it) { 547 WebPage* page = (*it).value.get(); 548 if (page->windowAndWebPageAreFocused()) 549 return page; 550 } 551 return 0; 552} 553 554#if PLATFORM(MAC) 555void WebProcess::setProcessSuppressionEnabled(bool processSuppressionEnabled) 556{ 557 HashMap<uint64_t, RefPtr<WebPage> >::const_iterator end = m_pageMap.end(); 558 for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator it = m_pageMap.begin(); it != end; ++it) { 559 WebPage* page = (*it).value.get(); 560 page->setThrottled(processSuppressionEnabled); 561 } 562 563 ChildProcess::setProcessSuppressionEnabled(processSuppressionEnabled); 564} 565#endif 566 567WebPage* WebProcess::webPage(uint64_t pageID) const 568{ 569 return m_pageMap.get(pageID); 570} 571 572void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& parameters) 573{ 574 // It is necessary to check for page existence here since during a window.open() (or targeted 575 // link) the WebPage gets created both in the synchronous handler and through the normal way. 576 HashMap<uint64_t, RefPtr<WebPage>>::AddResult result = m_pageMap.add(pageID, 0); 577 if (result.isNewEntry) { 578 ASSERT(!result.iterator->value); 579 result.iterator->value = WebPage::create(pageID, parameters); 580 581 // Balanced by an enableTermination in removeWebPage. 582 disableTermination(); 583 } 584 585 ASSERT(result.iterator->value); 586} 587 588void WebProcess::removeWebPage(uint64_t pageID) 589{ 590 ASSERT(m_pageMap.contains(pageID)); 591 592 pageWillLeaveWindow(pageID); 593 m_pageMap.remove(pageID); 594 595 enableTermination(); 596} 597 598bool WebProcess::shouldTerminate() 599{ 600 ASSERT(m_pageMap.isEmpty()); 601 602#if ENABLE(NETWORK_PROCESS) 603 ASSERT(m_usesNetworkProcess || !downloadManager().isDownloading()); 604#else 605 ASSERT(!downloadManager().isDownloading()); 606#endif 607 608 // FIXME: the ShouldTerminate message should also send termination parameters, such as any session cookies that need to be preserved. 609 bool shouldTerminate = false; 610 if (parentProcessConnection()->sendSync(Messages::WebProcessProxy::ShouldTerminate(), Messages::WebProcessProxy::ShouldTerminate::Reply(shouldTerminate), 0) 611 && !shouldTerminate) 612 return false; 613 614 return true; 615} 616 617void WebProcess::terminate() 618{ 619#ifndef NDEBUG 620 gcController().garbageCollectNow(); 621 memoryCache()->setDisabled(true); 622#endif 623 624 m_webConnection->invalidate(); 625 m_webConnection = nullptr; 626 627 platformTerminate(); 628 629 ChildProcess::terminate(); 630} 631 632void WebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder) 633{ 634 messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder); 635} 636 637void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder) 638{ 639 if (messageReceiverMap().dispatchMessage(connection, decoder)) 640 return; 641 642 if (decoder.messageReceiverName() == Messages::WebProcess::messageReceiverName()) { 643 didReceiveWebProcessMessage(connection, decoder); 644 return; 645 } 646 647 if (decoder.messageReceiverName() == Messages::WebPageGroupProxy::messageReceiverName()) { 648 uint64_t pageGroupID = decoder.destinationID(); 649 if (!pageGroupID) 650 return; 651 652 WebPageGroupProxy* pageGroupProxy = webPageGroup(pageGroupID); 653 if (!pageGroupProxy) 654 return; 655 656 pageGroupProxy->didReceiveMessage(connection, decoder); 657 } 658} 659 660void WebProcess::didClose(CoreIPC::Connection*) 661{ 662#ifndef NDEBUG 663 m_inDidClose = true; 664 665 // Close all the live pages. 666 Vector<RefPtr<WebPage>> pages; 667 copyValuesToVector(m_pageMap, pages); 668 for (size_t i = 0; i < pages.size(); ++i) 669 pages[i]->close(); 670 pages.clear(); 671 672 gcController().garbageCollectSoon(); 673 memoryCache()->setDisabled(true); 674#endif 675 676 // The UI process closed this connection, shut down. 677 stopRunLoop(); 678} 679 680void WebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference, CoreIPC::StringReference) 681{ 682 // We received an invalid message, but since this is from the UI process (which we trust), 683 // we'll let it slide. 684} 685 686WebFrame* WebProcess::webFrame(uint64_t frameID) const 687{ 688 return m_frameMap.get(frameID); 689} 690 691void WebProcess::addWebFrame(uint64_t frameID, WebFrame* frame) 692{ 693 m_frameMap.set(frameID, frame); 694} 695 696void WebProcess::removeWebFrame(uint64_t frameID) 697{ 698 m_frameMap.remove(frameID); 699 700 // We can end up here after our connection has closed when WebCore's frame life-support timer 701 // fires when the application is shutting down. There's no need (and no way) to update the UI 702 // process in this case. 703 if (!parentProcessConnection()) 704 return; 705 706 parentProcessConnection()->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0); 707} 708 709WebPageGroupProxy* WebProcess::webPageGroup(PageGroup* pageGroup) 710{ 711 for (HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator it = m_pageGroupMap.begin(), end = m_pageGroupMap.end(); it != end; ++it) { 712 if (it->value->corePageGroup() == pageGroup) 713 return it->value.get(); 714 } 715 716 return 0; 717} 718 719WebPageGroupProxy* WebProcess::webPageGroup(uint64_t pageGroupID) 720{ 721 return m_pageGroupMap.get(pageGroupID); 722} 723 724WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupData) 725{ 726 HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::AddResult result = m_pageGroupMap.add(pageGroupData.pageGroupID, 0); 727 if (result.isNewEntry) { 728 ASSERT(!result.iterator->value); 729 result.iterator->value = WebPageGroupProxy::create(pageGroupData); 730 } 731 732 return result.iterator->value.get(); 733} 734 735void WebProcess::clearResourceCaches(ResourceCachesToClear resourceCachesToClear) 736{ 737 platformClearResourceCaches(resourceCachesToClear); 738 739 // Toggling the cache model like this forces the cache to evict all its in-memory resources. 740 // FIXME: We need a better way to do this. 741 CacheModel cacheModel = m_cacheModel; 742 setCacheModel(CacheModelDocumentViewer); 743 setCacheModel(cacheModel); 744 745 memoryCache()->evictResources(); 746 747 // Empty the cross-origin preflight cache. 748 CrossOriginPreflightResultCache::shared().empty(); 749} 750 751void WebProcess::clearApplicationCache() 752{ 753 // Empty the application cache. 754 cacheStorage().empty(); 755} 756 757#if ENABLE(NETSCAPE_PLUGIN_API) && !ENABLE(PLUGIN_PROCESS) 758void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint64_t callbackID) 759{ 760 HashSet<String> sitesSet; 761 762#if ENABLE(NETSCAPE_PLUGIN_API) 763 for (size_t i = 0; i < pluginPaths.size(); ++i) { 764 RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]); 765 if (!netscapePluginModule) 766 continue; 767 768 Vector<String> sites = netscapePluginModule->sitesWithData(); 769 for (size_t i = 0; i < sites.size(); ++i) 770 sitesSet.add(sites[i]); 771 } 772#else 773 UNUSED_PARAM(pluginPaths); 774#endif 775 776 Vector<String> sites; 777 copyToVector(sitesSet, sites); 778 779 parentProcessConnection()->send(Messages::WebProcessProxy::DidGetSitesWithPluginData(sites, callbackID), 0); 780} 781 782void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) 783{ 784#if ENABLE(NETSCAPE_PLUGIN_API) 785 for (size_t i = 0; i < pluginPaths.size(); ++i) { 786 RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]); 787 if (!netscapePluginModule) 788 continue; 789 790 if (sites.isEmpty()) { 791 // Clear everything. 792 netscapePluginModule->clearSiteData(String(), flags, maxAgeInSeconds); 793 continue; 794 } 795 796 for (size_t i = 0; i < sites.size(); ++i) 797 netscapePluginModule->clearSiteData(sites[i], flags, maxAgeInSeconds); 798 } 799#else 800 UNUSED_PARAM(pluginPaths); 801 UNUSED_PARAM(sites); 802 UNUSED_PARAM(flags); 803 UNUSED_PARAM(maxAgeInSeconds); 804#endif 805 806 parentProcessConnection()->send(Messages::WebProcessProxy::DidClearPluginSiteData(callbackID), 0); 807} 808#endif 809 810static inline void addCaseFoldedCharacters(StringHasher& hasher, const String& string) 811{ 812 if (string.isEmpty()) 813 return; 814 if (string.is8Bit()) 815 return hasher.addCharacters<LChar, CaseFoldingHash::foldCase<LChar>>(string.characters8(), string.length()); 816 return hasher.addCharacters<UChar, CaseFoldingHash::foldCase<UChar>>(string.characters16(), string.length()); 817} 818 819static unsigned hashForPlugInOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) 820{ 821 // We want to avoid concatenating the strings and then taking the hash, since that could lead to an expensive conversion. 822 // We also want to avoid using the hash() function in StringImpl or CaseFoldingHash because that masks out bits for the use of flags. 823 StringHasher hasher; 824 addCaseFoldedCharacters(hasher, pageOrigin); 825 hasher.addCharacter(0); 826 addCaseFoldedCharacters(hasher, pluginOrigin); 827 hasher.addCharacter(0); 828 addCaseFoldedCharacters(hasher, mimeType); 829 return hasher.hash(); 830} 831 832bool WebProcess::isPlugInAutoStartOriginHash(unsigned plugInOriginHash) 833{ 834 HashMap<unsigned, double>::const_iterator it = m_plugInAutoStartOriginHashes.find(plugInOriginHash); 835 if (it == m_plugInAutoStartOriginHashes.end()) 836 return false; 837 return currentTime() < it->value; 838} 839 840bool WebProcess::shouldPlugInAutoStartFromOrigin(const WebPage* page, const String& pageOrigin, const String& pluginOrigin, const String& mimeType) 841{ 842 if (m_plugInAutoStartOrigins.contains(pluginOrigin)) 843 return true; 844 845#ifdef ENABLE_PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC 846 // The plugin wasn't in the general whitelist, so check if it similar to the primary plugin for the page (if we've found one). 847 if (page && page->matchesPrimaryPlugIn(pageOrigin, pluginOrigin, mimeType)) 848 return true; 849#else 850 UNUSED_PARAM(page); 851#endif 852 853 // Lastly check against the more explicit hash list. 854 return isPlugInAutoStartOriginHash(hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType)); 855} 856 857void WebProcess::plugInDidStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) 858{ 859 if (pageOrigin.isEmpty()) { 860 LOG(Plugins, "Not adding empty page origin"); 861 return; 862 } 863 864 unsigned plugInOriginHash = hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType); 865 if (isPlugInAutoStartOriginHash(plugInOriginHash)) { 866 LOG(Plugins, "Hash %x already exists as auto-start origin (request for %s)", plugInOriginHash, pageOrigin.utf8().data()); 867 return; 868 } 869 870 // We might attempt to start another plugin before the didAddPlugInAutoStartOrigin message 871 // comes back from the parent process. Temporarily add this hash to the list with a thirty 872 // second timeout. That way, even if the parent decides not to add it, we'll only be 873 // incorrect for a little while. 874 m_plugInAutoStartOriginHashes.set(plugInOriginHash, currentTime() + 30 * 1000); 875 876 parentProcessConnection()->send(Messages::WebContext::AddPlugInAutoStartOriginHash(pageOrigin, plugInOriginHash), 0); 877} 878 879void WebProcess::didAddPlugInAutoStartOriginHash(unsigned plugInOriginHash, double expirationTime) 880{ 881 // When called, some web process (which also might be this one) added the origin for auto-starting, 882 // or received user interaction. 883 // Set the bit to avoid having redundantly call into the UI process upon user interaction. 884 m_plugInAutoStartOriginHashes.set(plugInOriginHash, expirationTime); 885} 886 887void WebProcess::resetPlugInAutoStartOriginHashes(const HashMap<unsigned, double>& hashes) 888{ 889 m_plugInAutoStartOriginHashes.swap(const_cast<HashMap<unsigned, double>&>(hashes)); 890} 891 892void WebProcess::plugInDidReceiveUserInteraction(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) 893{ 894 if (pageOrigin.isEmpty()) 895 return; 896 897 unsigned plugInOriginHash = hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType); 898 if (!plugInOriginHash) 899 return; 900 901 HashMap<unsigned, double>::iterator it = m_plugInAutoStartOriginHashes.find(plugInOriginHash); 902 if (it == m_plugInAutoStartOriginHashes.end()) 903 return; 904 if (it->value - currentTime() > plugInAutoStartExpirationTimeUpdateThreshold) 905 return; 906 907 parentProcessConnection()->send(Messages::WebContext::PlugInDidReceiveUserInteraction(plugInOriginHash), 0); 908} 909 910static void fromCountedSetToHashMap(TypeCountSet* countedSet, HashMap<String, uint64_t>& map) 911{ 912 TypeCountSet::const_iterator end = countedSet->end(); 913 for (TypeCountSet::const_iterator it = countedSet->begin(); it != end; ++it) 914 map.set(it->key, it->value); 915} 916 917static void getWebCoreMemoryCacheStatistics(Vector<HashMap<String, uint64_t>>& result) 918{ 919 String imagesString(ASCIILiteral("Images")); 920 String cssString(ASCIILiteral("CSS")); 921 String xslString(ASCIILiteral("XSL")); 922 String javaScriptString(ASCIILiteral("JavaScript")); 923 924 MemoryCache::Statistics memoryCacheStatistics = memoryCache()->getStatistics(); 925 926 HashMap<String, uint64_t> counts; 927 counts.set(imagesString, memoryCacheStatistics.images.count); 928 counts.set(cssString, memoryCacheStatistics.cssStyleSheets.count); 929 counts.set(xslString, memoryCacheStatistics.xslStyleSheets.count); 930 counts.set(javaScriptString, memoryCacheStatistics.scripts.count); 931 result.append(counts); 932 933 HashMap<String, uint64_t> sizes; 934 sizes.set(imagesString, memoryCacheStatistics.images.size); 935 sizes.set(cssString, memoryCacheStatistics.cssStyleSheets.size); 936 sizes.set(xslString, memoryCacheStatistics.xslStyleSheets.size); 937 sizes.set(javaScriptString, memoryCacheStatistics.scripts.size); 938 result.append(sizes); 939 940 HashMap<String, uint64_t> liveSizes; 941 liveSizes.set(imagesString, memoryCacheStatistics.images.liveSize); 942 liveSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.liveSize); 943 liveSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.liveSize); 944 liveSizes.set(javaScriptString, memoryCacheStatistics.scripts.liveSize); 945 result.append(liveSizes); 946 947 HashMap<String, uint64_t> decodedSizes; 948 decodedSizes.set(imagesString, memoryCacheStatistics.images.decodedSize); 949 decodedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.decodedSize); 950 decodedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.decodedSize); 951 decodedSizes.set(javaScriptString, memoryCacheStatistics.scripts.decodedSize); 952 result.append(decodedSizes); 953 954 HashMap<String, uint64_t> purgeableSizes; 955 purgeableSizes.set(imagesString, memoryCacheStatistics.images.purgeableSize); 956 purgeableSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgeableSize); 957 purgeableSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgeableSize); 958 purgeableSizes.set(javaScriptString, memoryCacheStatistics.scripts.purgeableSize); 959 result.append(purgeableSizes); 960 961 HashMap<String, uint64_t> purgedSizes; 962 purgedSizes.set(imagesString, memoryCacheStatistics.images.purgedSize); 963 purgedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgedSize); 964 purgedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgedSize); 965 purgedSizes.set(javaScriptString, memoryCacheStatistics.scripts.purgedSize); 966 result.append(purgedSizes); 967} 968 969void WebProcess::getWebCoreStatistics(uint64_t callbackID) 970{ 971 StatisticsData data; 972 973 // Gather JavaScript statistics. 974 { 975 JSLockHolder lock(JSDOMWindow::commonVM()); 976 data.statisticsNumbers.set(ASCIILiteral("JavaScriptObjectsCount"), JSDOMWindow::commonVM()->heap.objectCount()); 977 data.statisticsNumbers.set(ASCIILiteral("JavaScriptGlobalObjectsCount"), JSDOMWindow::commonVM()->heap.globalObjectCount()); 978 data.statisticsNumbers.set(ASCIILiteral("JavaScriptProtectedObjectsCount"), JSDOMWindow::commonVM()->heap.protectedObjectCount()); 979 data.statisticsNumbers.set(ASCIILiteral("JavaScriptProtectedGlobalObjectsCount"), JSDOMWindow::commonVM()->heap.protectedGlobalObjectCount()); 980 981 OwnPtr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonVM()->heap.protectedObjectTypeCounts()); 982 fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts); 983 984 OwnPtr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonVM()->heap.objectTypeCounts()); 985 fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts); 986 987 uint64_t javaScriptHeapSize = JSDOMWindow::commonVM()->heap.size(); 988 data.statisticsNumbers.set(ASCIILiteral("JavaScriptHeapSize"), javaScriptHeapSize); 989 data.statisticsNumbers.set(ASCIILiteral("JavaScriptFreeSize"), JSDOMWindow::commonVM()->heap.capacity() - javaScriptHeapSize); 990 } 991 992 WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics(); 993 data.statisticsNumbers.set(ASCIILiteral("FastMallocReservedVMBytes"), fastMallocStatistics.reservedVMBytes); 994 data.statisticsNumbers.set(ASCIILiteral("FastMallocCommittedVMBytes"), fastMallocStatistics.committedVMBytes); 995 data.statisticsNumbers.set(ASCIILiteral("FastMallocFreeListBytes"), fastMallocStatistics.freeListBytes); 996 997 // Gather icon statistics. 998 data.statisticsNumbers.set(ASCIILiteral("IconPageURLMappingCount"), iconDatabase().pageURLMappingCount()); 999 data.statisticsNumbers.set(ASCIILiteral("IconRetainedPageURLCount"), iconDatabase().retainedPageURLCount()); 1000 data.statisticsNumbers.set(ASCIILiteral("IconRecordCount"), iconDatabase().iconRecordCount()); 1001 data.statisticsNumbers.set(ASCIILiteral("IconsWithDataCount"), iconDatabase().iconRecordCountWithData()); 1002 1003 // Gather font statistics. 1004 data.statisticsNumbers.set(ASCIILiteral("CachedFontDataCount"), fontCache()->fontDataCount()); 1005 data.statisticsNumbers.set(ASCIILiteral("CachedFontDataInactiveCount"), fontCache()->inactiveFontDataCount()); 1006 1007 // Gather glyph page statistics. 1008 data.statisticsNumbers.set(ASCIILiteral("GlyphPageCount"), GlyphPageTreeNode::treeGlyphPageCount()); 1009 1010 // Get WebCore memory cache statistics 1011 getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics); 1012 1013 parentProcessConnection()->send(Messages::WebContext::DidGetStatistics(data, callbackID), 0); 1014} 1015 1016void WebProcess::garbageCollectJavaScriptObjects() 1017{ 1018 gcController().garbageCollectNow(); 1019} 1020 1021void WebProcess::setJavaScriptGarbageCollectorTimerEnabled(bool flag) 1022{ 1023 gcController().setJavaScriptGarbageCollectorTimerEnabled(flag); 1024} 1025 1026void WebProcess::postInjectedBundleMessage(const CoreIPC::DataReference& messageData) 1027{ 1028 InjectedBundle* injectedBundle = WebProcess::shared().injectedBundle(); 1029 if (!injectedBundle) 1030 return; 1031 1032 OwnPtr<CoreIPC::ArgumentDecoder> decoder = CoreIPC::ArgumentDecoder::create(messageData.data(), messageData.size()); 1033 1034 String messageName; 1035 if (!decoder->decode(messageName)) 1036 return; 1037 1038 RefPtr<APIObject> messageBody; 1039 InjectedBundleUserMessageDecoder messageBodyDecoder(messageBody); 1040 if (!decoder->decode(messageBodyDecoder)) 1041 return; 1042 1043 injectedBundle->didReceiveMessage(messageName, messageBody.get()); 1044} 1045 1046#if ENABLE(NETWORK_PROCESS) 1047NetworkProcessConnection* WebProcess::networkConnection() 1048{ 1049 ASSERT(m_usesNetworkProcess); 1050 1051 // If we've lost our connection to the network process (e.g. it crashed) try to re-establish it. 1052 if (!m_networkProcessConnection) 1053 ensureNetworkProcessConnection(); 1054 1055 // If we failed to re-establish it then we are beyond recovery and should crash. 1056 if (!m_networkProcessConnection) 1057 CRASH(); 1058 1059 return m_networkProcessConnection.get(); 1060} 1061 1062void WebProcess::networkProcessConnectionClosed(NetworkProcessConnection* connection) 1063{ 1064 ASSERT(m_networkProcessConnection); 1065 ASSERT(m_networkProcessConnection == connection); 1066 1067 m_networkProcessConnection = 0; 1068 1069 m_webResourceLoadScheduler->networkProcessCrashed(); 1070} 1071 1072WebResourceLoadScheduler& WebProcess::webResourceLoadScheduler() 1073{ 1074 return *m_webResourceLoadScheduler; 1075} 1076#endif 1077 1078void WebProcess::downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, const ResourceRequest& request) 1079{ 1080 WebPage* initiatingPage = initiatingPageID ? webPage(initiatingPageID) : 0; 1081 1082 ResourceRequest requestWithOriginalURL = request; 1083 if (initiatingPage) 1084 initiatingPage->mainFrame()->loader()->setOriginalURLForDownloadRequest(requestWithOriginalURL); 1085 1086 downloadManager().startDownload(downloadID, requestWithOriginalURL); 1087} 1088 1089void WebProcess::cancelDownload(uint64_t downloadID) 1090{ 1091 downloadManager().cancelDownload(downloadID); 1092} 1093 1094#if PLATFORM(QT) 1095void WebProcess::startTransfer(uint64_t downloadID, const String& destination) 1096{ 1097 downloadManager().startTransfer(downloadID, destination); 1098} 1099#endif 1100 1101void WebProcess::setEnhancedAccessibility(bool flag) 1102{ 1103 WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility(flag); 1104} 1105 1106void WebProcess::startMemorySampler(const SandboxExtension::Handle& sampleLogFileHandle, const String& sampleLogFilePath, const double interval) 1107{ 1108#if ENABLE(MEMORY_SAMPLER) 1109 WebMemorySampler::shared()->start(sampleLogFileHandle, sampleLogFilePath, interval); 1110#endif 1111} 1112 1113void WebProcess::stopMemorySampler() 1114{ 1115#if ENABLE(MEMORY_SAMPLER) 1116 WebMemorySampler::shared()->stop(); 1117#endif 1118} 1119 1120void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState) 1121{ 1122 bool continuousSpellCheckingTurnedOff = !textCheckerState.isContinuousSpellCheckingEnabled && m_textCheckerState.isContinuousSpellCheckingEnabled; 1123 bool grammarCheckingTurnedOff = !textCheckerState.isGrammarCheckingEnabled && m_textCheckerState.isGrammarCheckingEnabled; 1124 1125 m_textCheckerState = textCheckerState; 1126 1127 if (!continuousSpellCheckingTurnedOff && !grammarCheckingTurnedOff) 1128 return; 1129 1130 HashMap<uint64_t, RefPtr<WebPage>>::iterator end = m_pageMap.end(); 1131 for (HashMap<uint64_t, RefPtr<WebPage>>::iterator it = m_pageMap.begin(); it != end; ++it) { 1132 WebPage* page = (*it).value.get(); 1133 if (continuousSpellCheckingTurnedOff) 1134 page->unmarkAllMisspellings(); 1135 if (grammarCheckingTurnedOff) 1136 page->unmarkAllBadGrammar(); 1137 } 1138} 1139 1140void WebProcess::releasePageCache() 1141{ 1142 int savedPageCacheCapacity = pageCache()->capacity(); 1143 pageCache()->setCapacity(0); 1144 pageCache()->setCapacity(savedPageCacheCapacity); 1145} 1146 1147#if !PLATFORM(MAC) 1148void WebProcess::initializeProcessName(const ChildProcessInitializationParameters&) 1149{ 1150} 1151 1152void WebProcess::initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&) 1153{ 1154} 1155 1156void WebProcess::platformInitializeProcess(const ChildProcessInitializationParameters&) 1157{ 1158} 1159 1160void WebProcess::updateActivePages() 1161{ 1162} 1163 1164#endif 1165 1166void WebProcess::pageDidEnterWindow(uint64_t pageID) 1167{ 1168 m_pagesInWindows.add(pageID); 1169 m_nonVisibleProcessCleanupTimer.stop(); 1170} 1171 1172void WebProcess::pageWillLeaveWindow(uint64_t pageID) 1173{ 1174 m_pagesInWindows.remove(pageID); 1175 1176 if (m_pagesInWindows.isEmpty() && !m_nonVisibleProcessCleanupTimer.isActive()) 1177 m_nonVisibleProcessCleanupTimer.startOneShot(nonVisibleProcessCleanupDelay); 1178} 1179 1180void WebProcess::nonVisibleProcessCleanupTimerFired(Timer<WebProcess>*) 1181{ 1182 ASSERT(m_pagesInWindows.isEmpty()); 1183 if (!m_pagesInWindows.isEmpty()) 1184 return; 1185 1186#if PLATFORM(MAC) 1187 wkDestroyRenderingResources(); 1188#endif 1189} 1190 1191void WebProcess::setMemoryCacheDisabled(bool disabled) 1192{ 1193 if (memoryCache()->disabled() != disabled) 1194 memoryCache()->setDisabled(disabled); 1195} 1196 1197} // namespace WebKit 1198