diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-13 12:51:20 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 20:50:05 +0200 |
commit | d441d6f39bb846989d95bcf5caf387b42414718d (patch) | |
tree | e367e64a75991c554930278175d403c072de6bb8 /Source/WebKit2/WebProcess/WebProcess.cpp | |
parent | 0060b2994c07842f4c59de64b5e3e430525c4b90 (diff) | |
download | qtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz |
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit.
Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebKit2/WebProcess/WebProcess.cpp')
-rw-r--r-- | Source/WebKit2/WebProcess/WebProcess.cpp | 825 |
1 files changed, 422 insertions, 403 deletions
diff --git a/Source/WebKit2/WebProcess/WebProcess.cpp b/Source/WebKit2/WebProcess/WebProcess.cpp index 1621612f2..33d30cf05 100644 --- a/Source/WebKit2/WebProcess/WebProcess.cpp +++ b/Source/WebKit2/WebProcess/WebProcess.cpp @@ -26,24 +26,27 @@ #include "config.h" #include "WebProcess.h" -#include "DownloadManager.h" +#include "AuthenticationManager.h" +#include "EventDispatcher.h" #include "InjectedBundle.h" #include "InjectedBundleUserMessageCoders.h" -#include "SandboxExtension.h" +#include "Logging.h" +#include "PluginProcessConnectionManager.h" #include "StatisticsData.h" #include "WebApplicationCacheManager.h" +#include "WebConnectionToUIProcess.h" #include "WebContextMessages.h" #include "WebCookieManager.h" #include "WebCoreArgumentCoders.h" -#include "WebDatabaseManager.h" #include "WebFrame.h" #include "WebFrameNetworkingContext.h" -#include "WebGeolocationManagerMessages.h" -#include "WebKeyValueStorageManager.h" +#include "WebGeolocationManager.h" +#include "WebIconDatabaseProxy.h" #include "WebMediaCacheManager.h" #include "WebMemorySampler.h" #include "WebPage.h" #include "WebPageCreationParameters.h" +#include "WebPageGroupProxyMessages.h" #include "WebPlatformStrategies.h" #include "WebPreferencesStore.h" #include "WebProcessCreationParameters.h" @@ -54,16 +57,17 @@ #include <JavaScriptCore/MemoryStatistics.h> #include <WebCore/AXObjectCache.h> #include <WebCore/ApplicationCacheStorage.h> +#include <WebCore/AuthenticationChallenge.h> #include <WebCore/CrossOriginPreflightResultCache.h> #include <WebCore/Font.h> #include <WebCore/FontCache.h> #include <WebCore/Frame.h> +#include <WebCore/FrameLoader.h> #include <WebCore/GCController.h> #include <WebCore/GlyphPageTreeNode.h> #include <WebCore/IconDatabase.h> #include <WebCore/JSDOMWindow.h> #include <WebCore/Language.h> -#include <WebCore/Logging.h> #include <WebCore/MemoryCache.h> #include <WebCore/MemoryPressureHandler.h> #include <WebCore/Page.h> @@ -75,19 +79,18 @@ #include <WebCore/SecurityOrigin.h> #include <WebCore/Settings.h> #include <WebCore/StorageTracker.h> +#include <wtf/CurrentTime.h> #include <wtf/HashCountedSet.h> #include <wtf/PassRefPtr.h> -#include <wtf/RandomNumber.h> - -#if ENABLE(WEB_INTENTS) -#include <WebCore/PlatformMessagePortChannel.h> -#endif +#include <wtf/text/StringHash.h> #if ENABLE(NETWORK_INFO) +#include "WebNetworkInfoManager.h" #include "WebNetworkInfoManagerMessages.h" #endif #if ENABLE(NETWORK_PROCESS) +#include "CookieStorageShim.h" #include "NetworkProcessConnection.h" #endif @@ -103,36 +106,44 @@ #include "CustomProtocolManager.h" #endif -using namespace JSC; -using namespace WebCore; +#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) +#include "WebNotificationManager.h" +#endif -namespace WebKit { +#if ENABLE(SQL_DATABASE) +#include "WebDatabaseManager.h" +#endif -#if OS(WINDOWS) -static void sleep(unsigned seconds) -{ - ::Sleep(seconds * 1000); -} +#if ENABLE(BATTERY_STATUS) +#include "WebBatteryManager.h" #endif -static void randomCrashThread(void*) NO_RETURN_DUE_TO_CRASH; -void randomCrashThread(void*) -{ - // This delay was chosen semi-arbitrarily. We want the crash to happen somewhat quickly to - // enable useful stress testing, but not so quickly that the web process will always crash soon - // after launch. - static const unsigned maximumRandomCrashDelay = 180; +#if ENABLE(NETWORK_PROCESS) +#include "WebResourceLoadScheduler.h" +#endif - sleep(randomNumber() * maximumRandomCrashDelay); - CRASH(); -} +#if ENABLE(PLUGIN_PROCESS) +#include "PluginProcessConnectionManager.h" +#endif -static void startRandomCrashThreadIfRequested() -{ - if (!getenv("WEBKIT2_CRASH_WEB_PROCESS_RANDOMLY")) - return; - createThread(randomCrashThread, 0, "WebKit2: Random Crash Thread"); -} +#if USE(SECURITY_FRAMEWORK) +#include "SecItemShim.h" +#endif + +#if USE(SOUP) +#include "WebSoupRequestManager.h" +#endif + +using namespace JSC; +using namespace WebCore; + +// This should be less than plugInAutoStartExpirationTimeThreshold in PlugInAutoStartProvider. +static const double plugInAutoStartExpirationTimeUpdateThreshold = 29 * 24 * 60 * 60; + +// This should be greater than tileRevalidationTimeout in TileController. +static const double nonVisibleProcessCleanupDelay = 10; + +namespace WebKit { WebProcess& WebProcess::shared() { @@ -141,7 +152,8 @@ WebProcess& WebProcess::shared() } WebProcess::WebProcess() - : m_inDidClose(false) + : m_eventDispatcher(EventDispatcher::create()) + , m_inDidClose(false) , m_shouldTrackVisitedLinks(true) , m_hasSetCacheModel(false) , m_cacheModel(CacheModelDocumentViewer) @@ -156,65 +168,102 @@ WebProcess::WebProcess() , m_networkAccessManager(0) #endif , m_textCheckerState() - , m_geolocationManager(this) -#if ENABLE(BATTERY_STATUS) - , m_batteryManager(this) -#endif -#if ENABLE(NETWORK_INFO) - , m_networkInfoManager(this) -#endif -#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) - , m_notificationManager(this) -#endif - , m_iconDatabaseProxy(this) + , m_iconDatabaseProxy(new WebIconDatabaseProxy(this)) #if ENABLE(NETWORK_PROCESS) , m_usesNetworkProcess(false) + , m_webResourceLoadScheduler(new WebResourceLoadScheduler) #endif -#if USE(SOUP) - , m_soupRequestManager(this) +#if ENABLE(PLUGIN_PROCESS) + , m_pluginProcessConnectionManager(PluginProcessConnectionManager::create()) #endif + , m_nonVisibleProcessCleanupTimer(this, &WebProcess::nonVisibleProcessCleanupTimerFired) { -#if USE(PLATFORM_STRATEGIES) // Initialize our platform strategies. WebPlatformStrategies::initialize(); -#endif // USE(PLATFORM_STRATEGIES) -#if !LOG_DISABLED - WebCore::initializeLoggingChannelsIfNecessary(); -#endif // !LOG_DISABLED + // FIXME: This should moved to where WebProcess::initialize is called, + // so that ports have a chance to customize, and ifdefs in this file are + // limited. + addSupplement<WebGeolocationManager>(); + addSupplement<WebApplicationCacheManager>(); + addSupplement<WebResourceCacheManager>(); + addSupplement<WebCookieManager>(); + addSupplement<WebMediaCacheManager>(); + addSupplement<AuthenticationManager>(); + +#if ENABLE(SQL_DATABASE) + addSupplement<WebDatabaseManager>(); +#endif +#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) + addSupplement<WebNotificationManager>(); +#endif +#if ENABLE(CUSTOM_PROTOCOLS) + addSupplement<CustomProtocolManager>(); +#endif +#if ENABLE(BATTERY_STATUS) + addSupplement<WebBatteryManager>(); +#endif +#if ENABLE(NETWORK_INFO) + addSupplement<WebNetworkInfoManager>(); +#endif +#if USE(SOUP) + addSupplement<WebSoupRequestManager>(); +#endif +} + +void WebProcess::initializeProcess(const ChildProcessInitializationParameters& parameters) +{ + platformInitializeProcess(parameters); } -void WebProcess::initialize(CoreIPC::Connection::Identifier serverIdentifier, RunLoop* runLoop) +void WebProcess::initializeConnection(CoreIPC::Connection* connection) { - ASSERT(!m_connection); + ChildProcess::initializeConnection(connection); - m_connection = CoreIPC::Connection::createClientConnection(serverIdentifier, this, runLoop); - m_connection->setDidCloseOnConnectionWorkQueueCallback(ChildProcess::didCloseOnConnectionWorkQueue); - m_connection->setShouldExitOnSyncMessageSendFailure(true); - m_connection->addQueueClient(&m_eventDispatcher); - m_connection->addQueueClient(this); - m_connection->open(); + connection->setShouldExitOnSyncMessageSendFailure(true); + + m_eventDispatcher->initializeConnection(connection); + +#if ENABLE(PLUGIN_PROCESS) + m_pluginProcessConnectionManager->initializeConnection(connection); +#endif + +#if USE(SECURITY_FRAMEWORK) + SecItemShim::shared().initializeConnection(connection); +#endif + + WebProcessSupplementMap::const_iterator it = m_supplements.begin(); + WebProcessSupplementMap::const_iterator end = m_supplements.end(); + for (; it != end; ++it) + it->value->initializeConnection(connection); m_webConnection = WebConnectionToUIProcess::create(this); - m_runLoop = runLoop; + // In order to ensure that the asynchronous messages that are used for notifying the UI process + // about when WebFrame objects come and go are always delivered before the synchronous policy messages, + // use this flag to force synchronous messages to be treated as asynchronous messages in the UI process + // unless when doing so would lead to a deadlock. + connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true); +} - startRandomCrashThreadIfRequested(); +void WebProcess::didCreateDownload() +{ + disableTermination(); } -void WebProcess::addMessageReceiver(CoreIPC::StringReference messageReceiverName, CoreIPC::MessageReceiver* messageReceiver) +void WebProcess::didDestroyDownload() { - m_messageReceiverMap.addMessageReceiver(messageReceiverName, messageReceiver); + enableTermination(); } -void WebProcess::addMessageReceiver(CoreIPC::StringReference messageReceiverName, uint64_t destinationID, CoreIPC::MessageReceiver* messageReceiver) +CoreIPC::Connection* WebProcess::downloadProxyConnection() { - m_messageReceiverMap.addMessageReceiver(messageReceiverName, destinationID, messageReceiver); + return parentProcessConnection(); } -void WebProcess::removeMessageReceiver(CoreIPC::StringReference messageReceiverName, uint64_t destinationID) +AuthenticationManager& WebProcess::downloadsAuthenticationManager() { - m_messageReceiverMap.removeMessageReceiver(messageReceiverName, destinationID); + return *supplement<AuthenticationManager>(); } void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::MessageDecoder& decoder) @@ -240,18 +289,15 @@ void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parame } } -#if ENABLE(SQL_DATABASE) - // Make sure the WebDatabaseManager is initialized so that the Database directory is set. - WebDatabaseManager::initialize(parameters.databaseDirectory); -#endif + WebProcessSupplementMap::const_iterator it = m_supplements.begin(); + WebProcessSupplementMap::const_iterator end = m_supplements.end(); + for (; it != end; ++it) + it->value->initialize(parameters); #if ENABLE(ICONDATABASE) - m_iconDatabaseProxy.setEnabled(parameters.iconDatabaseEnabled); + m_iconDatabaseProxy->setEnabled(parameters.iconDatabaseEnabled); #endif - StorageTracker::initializeTracker(parameters.localStorageDirectory, &WebKeyValueStorageManager::shared()); - m_localStorageDirectory = parameters.localStorageDirectory; - if (!parameters.applicationCacheDirectory.isEmpty()) cacheStorage().setCacheDirectory(parameters.applicationCacheDirectory); @@ -274,6 +320,18 @@ void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parame for (size_t i = 0; i < parameters.urlSchemesForWhichDomainRelaxationIsForbidden.size(); ++i) setDomainRelaxationForbiddenForURLScheme(parameters.urlSchemesForWhichDomainRelaxationIsForbidden[i]); + for (size_t i = 0; i < parameters.urlSchemesRegisteredAsLocal.size(); ++i) + registerURLSchemeAsLocal(parameters.urlSchemesRegisteredAsLocal[i]); + + for (size_t i = 0; i < parameters.urlSchemesRegisteredAsNoAccess.size(); ++i) + registerURLSchemeAsNoAccess(parameters.urlSchemesRegisteredAsNoAccess[i]); + + for (size_t i = 0; i < parameters.urlSchemesRegisteredAsDisplayIsolated.size(); ++i) + registerURLSchemeAsDisplayIsolated(parameters.urlSchemesRegisteredAsDisplayIsolated[i]); + + for (size_t i = 0; i < parameters.urlSchemesRegisteredAsCORSEnabled.size(); ++i) + registerURLSchemeAsCORSEnabled(parameters.urlSchemesRegisteredAsCORSEnabled[i]); + setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval); if (parameters.shouldAlwaysUseComplexTextCodePath) @@ -282,16 +340,22 @@ void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parame if (parameters.shouldUseFontSmoothing) setShouldUseFontSmoothing(true); -#if (PLATFORM(MAC) || USE(CFNETWORK)) && !PLATFORM(WIN) - // FIXME (NetworkProcess): Send this identifier to network process. +#if PLATFORM(MAC) || USE(CFNETWORK) WebFrameNetworkingContext::setPrivateBrowsingStorageSessionIdentifierBase(parameters.uiProcessBundleIdentifier); #endif #if ENABLE(NETWORK_PROCESS) m_usesNetworkProcess = parameters.usesNetworkProcess; ensureNetworkProcessConnection(); + + if (usesNetworkProcess()) + CookieStorageShim::shared().initialize(); #endif setTerminationTimeout(parameters.terminationTimeout); + + resetPlugInAutoStartOriginHashes(parameters.plugInAutoStartOriginHashes); + for (size_t i = 0; i < parameters.plugInAutoStartOrigins.size(); ++i) + m_plugInAutoStartOrigins.add(parameters.plugInAutoStartOrigins[i]); } #if ENABLE(NETWORK_PROCESS) @@ -305,7 +369,7 @@ void WebProcess::ensureNetworkProcessConnection() CoreIPC::Attachment encodedConnectionIdentifier; - if (!connection()->sendSync(Messages::WebProcessProxy::GetNetworkProcessConnection(), + if (!parentProcessConnection()->sendSync(Messages::WebProcessProxy::GetNetworkProcessConnection(), Messages::WebProcessProxy::GetNetworkProcessConnection::Reply(encodedConnectionIdentifier), 0)) return; @@ -387,6 +451,37 @@ void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled) m_fullKeyboardAccessEnabled = fullKeyboardAccessEnabled; } +void WebProcess::ensurePrivateBrowsingSession() +{ +#if PLATFORM(MAC) || USE(CFNETWORK) + WebFrameNetworkingContext::ensurePrivateBrowsingSession(); +#endif +} + +void WebProcess::destroyPrivateBrowsingSession() +{ +#if PLATFORM(MAC) || USE(CFNETWORK) + WebFrameNetworkingContext::destroyPrivateBrowsingSession(); +#endif +} + +DownloadManager& WebProcess::downloadManager() +{ +#if ENABLE(NETWORK_PROCESS) + ASSERT(!m_usesNetworkProcess); +#endif + + DEFINE_STATIC_LOCAL(DownloadManager, downloadManager, (this)); + return downloadManager; +} + +#if ENABLE(PLUGIN_PROCESS) +PluginProcessConnectionManager& WebProcess::pluginProcessConnectionManager() +{ + return *m_pluginProcessConnectionManager; +} +#endif + void WebProcess::setVisitedLinkTable(const SharedMemory::Handle& handle) { RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly); @@ -400,8 +495,8 @@ void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHa { // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext. for (size_t i = 0; i < linkHashes.size(); ++i) { - HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin(); - HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end(); + HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator it = m_pageGroupMap.begin(); + HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator end = m_pageGroupMap.end(); for (; it != end; ++it) Page::visitedStateChanged(PageGroup::pageGroup(it->value->identifier()), linkHashes[i]); } @@ -412,8 +507,8 @@ void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHa void WebProcess::allVisitedLinkStateChanged() { // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext. - HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin(); - HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end(); + HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator it = m_pageGroupMap.begin(); + HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator end = m_pageGroupMap.end(); for (; it != end; ++it) Page::allVisitedStateChanged(PageGroup::pageGroup(it->value->identifier())); @@ -429,7 +524,7 @@ void WebProcess::addVisitedLink(WebCore::LinkHash linkHash) { if (isLinkVisited(linkHash) || !m_shouldTrackVisitedLinks) return; - connection()->send(Messages::WebContext::AddVisitedLinkHash(linkHash), 0); + parentProcessConnection()->send(Messages::WebContext::AddVisitedLinkHash(linkHash), 0); } void WebProcess::setCacheModel(uint32_t cm) @@ -443,154 +538,10 @@ void WebProcess::setCacheModel(uint32_t cm) } } -void WebProcess::calculateCacheSizes(CacheModel cacheModel, uint64_t memorySize, uint64_t diskFreeSize, - unsigned& cacheTotalCapacity, unsigned& cacheMinDeadCapacity, unsigned& cacheMaxDeadCapacity, double& deadDecodedDataDeletionInterval, - unsigned& pageCacheCapacity, unsigned long& urlCacheMemoryCapacity, unsigned long& urlCacheDiskCapacity) -{ - switch (cacheModel) { - case CacheModelDocumentViewer: { - // Page cache capacity (in pages) - pageCacheCapacity = 0; - - // Object cache capacities (in bytes) - if (memorySize >= 2048) - cacheTotalCapacity = 96 * 1024 * 1024; - else if (memorySize >= 1536) - cacheTotalCapacity = 64 * 1024 * 1024; - else if (memorySize >= 1024) - cacheTotalCapacity = 32 * 1024 * 1024; - else if (memorySize >= 512) - cacheTotalCapacity = 16 * 1024 * 1024; - - cacheMinDeadCapacity = 0; - cacheMaxDeadCapacity = 0; - - // Foundation memory cache capacity (in bytes) - urlCacheMemoryCapacity = 0; - - // Foundation disk cache capacity (in bytes) - urlCacheDiskCapacity = 0; - - break; - } - case CacheModelDocumentBrowser: { - // Page cache capacity (in pages) - if (memorySize >= 1024) - pageCacheCapacity = 3; - else if (memorySize >= 512) - pageCacheCapacity = 2; - else if (memorySize >= 256) - pageCacheCapacity = 1; - else - pageCacheCapacity = 0; - - // Object cache capacities (in bytes) - if (memorySize >= 2048) - cacheTotalCapacity = 96 * 1024 * 1024; - else if (memorySize >= 1536) - cacheTotalCapacity = 64 * 1024 * 1024; - else if (memorySize >= 1024) - cacheTotalCapacity = 32 * 1024 * 1024; - else if (memorySize >= 512) - cacheTotalCapacity = 16 * 1024 * 1024; - - cacheMinDeadCapacity = cacheTotalCapacity / 8; - cacheMaxDeadCapacity = cacheTotalCapacity / 4; - - // Foundation memory cache capacity (in bytes) - if (memorySize >= 2048) - urlCacheMemoryCapacity = 4 * 1024 * 1024; - else if (memorySize >= 1024) - urlCacheMemoryCapacity = 2 * 1024 * 1024; - else if (memorySize >= 512) - urlCacheMemoryCapacity = 1 * 1024 * 1024; - else - urlCacheMemoryCapacity = 512 * 1024; - - // Foundation disk cache capacity (in bytes) - if (diskFreeSize >= 16384) - urlCacheDiskCapacity = 50 * 1024 * 1024; - else if (diskFreeSize >= 8192) - urlCacheDiskCapacity = 40 * 1024 * 1024; - else if (diskFreeSize >= 4096) - urlCacheDiskCapacity = 30 * 1024 * 1024; - else - urlCacheDiskCapacity = 20 * 1024 * 1024; - - break; - } - case CacheModelPrimaryWebBrowser: { - // Page cache capacity (in pages) - // (Research indicates that value / page drops substantially after 3 pages.) - if (memorySize >= 2048) - pageCacheCapacity = 5; - else if (memorySize >= 1024) - pageCacheCapacity = 4; - else if (memorySize >= 512) - pageCacheCapacity = 3; - else if (memorySize >= 256) - pageCacheCapacity = 2; - else - pageCacheCapacity = 1; - - // Object cache capacities (in bytes) - // (Testing indicates that value / MB depends heavily on content and - // browsing pattern. Even growth above 128MB can have substantial - // value / MB for some content / browsing patterns.) - if (memorySize >= 2048) - cacheTotalCapacity = 128 * 1024 * 1024; - else if (memorySize >= 1536) - cacheTotalCapacity = 96 * 1024 * 1024; - else if (memorySize >= 1024) - cacheTotalCapacity = 64 * 1024 * 1024; - else if (memorySize >= 512) - cacheTotalCapacity = 32 * 1024 * 1024; - - cacheMinDeadCapacity = cacheTotalCapacity / 4; - cacheMaxDeadCapacity = cacheTotalCapacity / 2; - - // This code is here to avoid a PLT regression. We can remove it if we - // can prove that the overall system gain would justify the regression. - cacheMaxDeadCapacity = std::max(24u, cacheMaxDeadCapacity); - - deadDecodedDataDeletionInterval = 60; - - // Foundation memory cache capacity (in bytes) - // (These values are small because WebCore does most caching itself.) - if (memorySize >= 1024) - urlCacheMemoryCapacity = 4 * 1024 * 1024; - else if (memorySize >= 512) - urlCacheMemoryCapacity = 2 * 1024 * 1024; - else if (memorySize >= 256) - urlCacheMemoryCapacity = 1 * 1024 * 1024; - else - urlCacheMemoryCapacity = 512 * 1024; - - // Foundation disk cache capacity (in bytes) - if (diskFreeSize >= 16384) - urlCacheDiskCapacity = 175 * 1024 * 1024; - else if (diskFreeSize >= 8192) - urlCacheDiskCapacity = 150 * 1024 * 1024; - else if (diskFreeSize >= 4096) - urlCacheDiskCapacity = 125 * 1024 * 1024; - else if (diskFreeSize >= 2048) - urlCacheDiskCapacity = 100 * 1024 * 1024; - else if (diskFreeSize >= 1024) - urlCacheDiskCapacity = 75 * 1024 * 1024; - else - urlCacheDiskCapacity = 50 * 1024 * 1024; - - break; - } - default: - ASSERT_NOT_REACHED(); - }; -} - WebPage* WebProcess::focusedWebPage() const { - HashMap<uint64_t, RefPtr<WebPage> >::const_iterator end = m_pageMap.end(); - for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator it = m_pageMap.begin(); it != end; ++it) { + HashMap<uint64_t, RefPtr<WebPage>>::const_iterator end = m_pageMap.end(); + for (HashMap<uint64_t, RefPtr<WebPage>>::const_iterator it = m_pageMap.begin(); it != end; ++it) { WebPage* page = (*it).value.get(); if (page->windowAndWebPageAreFocused()) return page; @@ -598,16 +549,29 @@ WebPage* WebProcess::focusedWebPage() const return 0; } +#if PLATFORM(MAC) +void WebProcess::setProcessSuppressionEnabled(bool processSuppressionEnabled) +{ + HashMap<uint64_t, RefPtr<WebPage> >::const_iterator end = m_pageMap.end(); + for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator it = m_pageMap.begin(); it != end; ++it) { + WebPage* page = (*it).value.get(); + page->setThrottled(processSuppressionEnabled); + } + + ChildProcess::setProcessSuppressionEnabled(processSuppressionEnabled); +} +#endif + WebPage* WebProcess::webPage(uint64_t pageID) const { - return m_pageMap.get(pageID).get(); + return m_pageMap.get(pageID); } void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& parameters) { // It is necessary to check for page existence here since during a window.open() (or targeted // link) the WebPage gets created both in the synchronous handler and through the normal way. - HashMap<uint64_t, RefPtr<WebPage> >::AddResult result = m_pageMap.add(pageID, 0); + HashMap<uint64_t, RefPtr<WebPage>>::AddResult result = m_pageMap.add(pageID, 0); if (result.isNewEntry) { ASSERT(!result.iterator->value); result.iterator->value = WebPage::create(pageID, parameters); @@ -623,29 +587,25 @@ void WebProcess::removeWebPage(uint64_t pageID) { ASSERT(m_pageMap.contains(pageID)); + pageWillLeaveWindow(pageID); m_pageMap.remove(pageID); enableTermination(); } -bool WebProcess::isSeparateProcess() const -{ - // If we're running on the main run loop, we assume that we're in a separate process. - return m_runLoop == RunLoop::main(); -} - bool WebProcess::shouldTerminate() { - // Keep running forever if we're running in the same process. - if (!isSeparateProcess()) - return false; - ASSERT(m_pageMap.isEmpty()); - ASSERT(!DownloadManager::shared().isDownloading()); + +#if ENABLE(NETWORK_PROCESS) + ASSERT(m_usesNetworkProcess || !downloadManager().isDownloading()); +#else + ASSERT(!downloadManager().isDownloading()); +#endif // FIXME: the ShouldTerminate message should also send termination parameters, such as any session cookies that need to be preserved. bool shouldTerminate = false; - if (connection()->sendSync(Messages::WebProcessProxy::ShouldTerminate(), Messages::WebProcessProxy::ShouldTerminate::Reply(shouldTerminate), 0) + if (parentProcessConnection()->sendSync(Messages::WebProcessProxy::ShouldTerminate(), Messages::WebProcessProxy::ShouldTerminate::Reply(shouldTerminate), 0) && !shouldTerminate) return false; @@ -656,76 +616,34 @@ void WebProcess::terminate() { #ifndef NDEBUG gcController().garbageCollectNow(); + fontCache()->invalidate(); memoryCache()->setDisabled(true); #endif - // Invalidate our connection. - m_connection->invalidate(); - m_connection = nullptr; - m_webConnection->invalidate(); m_webConnection = nullptr; platformTerminate(); - m_runLoop->stop(); + + ChildProcess::terminate(); } -void WebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder) +void WebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder) { - m_messageReceiverMap.dispatchSyncMessage(connection, messageID, decoder, replyEncoder); - return; + messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder); } -void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::MessageDecoder& decoder) +void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder) { - if (m_messageReceiverMap.dispatchMessage(connection, messageID, decoder)) + if (messageReceiverMap().dispatchMessage(connection, decoder)) return; - if (messageID.is<CoreIPC::MessageClassWebProcess>()) { - didReceiveWebProcessMessage(connection, messageID, decoder); + if (decoder.messageReceiverName() == Messages::WebProcess::messageReceiverName()) { + didReceiveWebProcessMessage(connection, decoder); return; } - if (messageID.is<CoreIPC::MessageClassWebApplicationCacheManager>()) { - WebApplicationCacheManager::shared().didReceiveMessage(connection, messageID, decoder); - return; - } - - if (messageID.is<CoreIPC::MessageClassWebCookieManager>()) { - WebCookieManager::shared().didReceiveMessage(connection, messageID, decoder); - return; - } - -#if ENABLE(SQL_DATABASE) - if (messageID.is<CoreIPC::MessageClassWebDatabaseManager>()) { - WebDatabaseManager::shared().didReceiveMessage(connection, messageID, decoder); - return; - } -#endif - - if (messageID.is<CoreIPC::MessageClassWebKeyValueStorageManager>()) { - WebKeyValueStorageManager::shared().didReceiveMessage(connection, messageID, decoder); - return; - } - - if (messageID.is<CoreIPC::MessageClassWebMediaCacheManager>()) { - WebMediaCacheManager::shared().didReceiveMessage(connection, messageID, decoder); - return; - } - - if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) { - WebResourceCacheManager::shared().didReceiveMessage(connection, messageID, decoder); - return; - } - -#if ENABLE(CUSTOM_PROTOCOLS) - if (messageID.is<CoreIPC::MessageClassCustomProtocolManager>()) { - CustomProtocolManager::shared().didReceiveMessage(connection, messageID, decoder); - return; - } -#endif - - if (messageID.is<CoreIPC::MessageClassWebPageGroupProxy>()) { + if (decoder.messageReceiverName() == Messages::WebPageGroupProxy::messageReceiverName()) { uint64_t pageGroupID = decoder.destinationID(); if (!pageGroupID) return; @@ -734,31 +652,29 @@ void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::Mes if (!pageGroupProxy) return; - pageGroupProxy->didReceiveMessage(connection, messageID, decoder); + pageGroupProxy->didReceiveMessage(connection, decoder); } } void WebProcess::didClose(CoreIPC::Connection*) { - // When running in the same process the connection will never be closed. - ASSERT(isSeparateProcess()); - #ifndef NDEBUG m_inDidClose = true; // Close all the live pages. - Vector<RefPtr<WebPage> > pages; + Vector<RefPtr<WebPage>> pages; copyValuesToVector(m_pageMap, pages); for (size_t i = 0; i < pages.size(); ++i) pages[i]->close(); pages.clear(); gcController().garbageCollectSoon(); + fontCache()->invalidate(); memoryCache()->setDisabled(true); #endif // The UI process closed this connection, shut down. - m_runLoop->stop(); + RunLoop::main()->stop(); } void WebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference, CoreIPC::StringReference) @@ -767,14 +683,6 @@ void WebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringR // we'll let it slide. } -void WebProcess::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::MessageDecoder& decoder, bool& didHandleMessage) -{ - if (messageID.is<CoreIPC::MessageClassWebProcess>()) { - didReceiveWebProcessMessageOnConnectionWorkQueue(connection, messageID, decoder, didHandleMessage); - return; - } -} - WebFrame* WebProcess::webFrame(uint64_t frameID) const { return m_frameMap.get(frameID); @@ -792,20 +700,30 @@ void WebProcess::removeWebFrame(uint64_t frameID) // We can end up here after our connection has closed when WebCore's frame life-support timer // fires when the application is shutting down. There's no need (and no way) to update the UI // process in this case. - if (!m_connection) + if (!parentProcessConnection()) return; - connection()->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0); + parentProcessConnection()->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0); +} + +WebPageGroupProxy* WebProcess::webPageGroup(PageGroup* pageGroup) +{ + for (HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::const_iterator it = m_pageGroupMap.begin(), end = m_pageGroupMap.end(); it != end; ++it) { + if (it->value->corePageGroup() == pageGroup) + return it->value.get(); + } + + return 0; } WebPageGroupProxy* WebProcess::webPageGroup(uint64_t pageGroupID) { - return m_pageGroupMap.get(pageGroupID).get(); + return m_pageGroupMap.get(pageGroupID); } WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupData) { - HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::AddResult result = m_pageGroupMap.add(pageGroupData.pageGroupID, 0); + HashMap<uint64_t, RefPtr<WebPageGroupProxy>>::AddResult result = m_pageGroupMap.add(pageGroupData.pageGroupID, 0); if (result.isNewEntry) { ASSERT(!result.iterator->value); result.iterator->value = WebPageGroupProxy::create(pageGroupData); @@ -814,26 +732,6 @@ WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupDat return result.iterator->value.get(); } -#if ENABLE(WEB_INTENTS) -uint64_t WebProcess::addMessagePortChannel(PassRefPtr<PlatformMessagePortChannel> messagePortChannel) -{ - static uint64_t channelID = 0; - m_messagePortChannels.add(++channelID, messagePortChannel); - - return channelID; -} - -PlatformMessagePortChannel* WebProcess::messagePortChannel(uint64_t channelID) -{ - return m_messagePortChannels.get(channelID).get(); -} - -void WebProcess::removeMessagePortChannel(uint64_t channelID) -{ - m_messagePortChannels.remove(channelID); -} -#endif - void WebProcess::clearResourceCaches(ResourceCachesToClear resourceCachesToClear) { platformClearResourceCaches(resourceCachesToClear); @@ -859,8 +757,6 @@ void WebProcess::clearApplicationCache() #if ENABLE(NETSCAPE_PLUGIN_API) && !ENABLE(PLUGIN_PROCESS) void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint64_t callbackID) { - LocalTerminationDisabler terminationDisabler(*this); - HashSet<String> sitesSet; #if ENABLE(NETSCAPE_PLUGIN_API) @@ -880,13 +776,11 @@ void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint6 Vector<String> sites; copyToVector(sitesSet, sites); - connection()->send(Messages::WebProcessProxy::DidGetSitesWithPluginData(sites, callbackID), 0); + parentProcessConnection()->send(Messages::WebProcessProxy::DidGetSitesWithPluginData(sites, callbackID), 0); } void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) { - LocalTerminationDisabler terminationDisabler(*this); - #if ENABLE(NETSCAPE_PLUGIN_API) for (size_t i = 0; i < pluginPaths.size(); ++i) { RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]); @@ -909,10 +803,110 @@ void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Ve UNUSED_PARAM(maxAgeInSeconds); #endif - connection()->send(Messages::WebProcessProxy::DidClearPluginSiteData(callbackID), 0); + parentProcessConnection()->send(Messages::WebProcessProxy::DidClearPluginSiteData(callbackID), 0); } #endif - + +static inline void addCaseFoldedCharacters(StringHasher& hasher, const String& string) +{ + if (string.isEmpty()) + return; + if (string.is8Bit()) + return hasher.addCharacters<LChar, CaseFoldingHash::foldCase<LChar>>(string.characters8(), string.length()); + return hasher.addCharacters<UChar, CaseFoldingHash::foldCase<UChar>>(string.characters16(), string.length()); +} + +static unsigned hashForPlugInOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) +{ + // We want to avoid concatenating the strings and then taking the hash, since that could lead to an expensive conversion. + // We also want to avoid using the hash() function in StringImpl or CaseFoldingHash because that masks out bits for the use of flags. + StringHasher hasher; + addCaseFoldedCharacters(hasher, pageOrigin); + hasher.addCharacter(0); + addCaseFoldedCharacters(hasher, pluginOrigin); + hasher.addCharacter(0); + addCaseFoldedCharacters(hasher, mimeType); + return hasher.hash(); +} + +bool WebProcess::isPlugInAutoStartOriginHash(unsigned plugInOriginHash) +{ + HashMap<unsigned, double>::const_iterator it = m_plugInAutoStartOriginHashes.find(plugInOriginHash); + if (it == m_plugInAutoStartOriginHashes.end()) + return false; + return currentTime() < it->value; +} + +bool WebProcess::shouldPlugInAutoStartFromOrigin(const WebPage* page, const String& pageOrigin, const String& pluginOrigin, const String& mimeType) +{ + if (m_plugInAutoStartOrigins.contains(pluginOrigin)) + return true; + +#ifdef ENABLE_PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC + // 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). + if (page && page->matchesPrimaryPlugIn(pageOrigin, pluginOrigin, mimeType)) + return true; +#else + UNUSED_PARAM(page); +#endif + + // Lastly check against the more explicit hash list. + return isPlugInAutoStartOriginHash(hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType)); +} + +void WebProcess::plugInDidStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) +{ + if (pageOrigin.isEmpty()) { + LOG(Plugins, "Not adding empty page origin"); + return; + } + + unsigned plugInOriginHash = hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType); + if (isPlugInAutoStartOriginHash(plugInOriginHash)) { + LOG(Plugins, "Hash %x already exists as auto-start origin (request for %s)", plugInOriginHash, pageOrigin.utf8().data()); + return; + } + + // We might attempt to start another plugin before the didAddPlugInAutoStartOrigin message + // comes back from the parent process. Temporarily add this hash to the list with a thirty + // second timeout. That way, even if the parent decides not to add it, we'll only be + // incorrect for a little while. + m_plugInAutoStartOriginHashes.set(plugInOriginHash, currentTime() + 30 * 1000); + + parentProcessConnection()->send(Messages::WebContext::AddPlugInAutoStartOriginHash(pageOrigin, plugInOriginHash), 0); +} + +void WebProcess::didAddPlugInAutoStartOriginHash(unsigned plugInOriginHash, double expirationTime) +{ + // When called, some web process (which also might be this one) added the origin for auto-starting, + // or received user interaction. + // Set the bit to avoid having redundantly call into the UI process upon user interaction. + m_plugInAutoStartOriginHashes.set(plugInOriginHash, expirationTime); +} + +void WebProcess::resetPlugInAutoStartOriginHashes(const HashMap<unsigned, double>& hashes) +{ + m_plugInAutoStartOriginHashes.swap(const_cast<HashMap<unsigned, double>&>(hashes)); +} + +void WebProcess::plugInDidReceiveUserInteraction(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) +{ + if (pageOrigin.isEmpty()) + return; + + unsigned plugInOriginHash = hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType); + if (!plugInOriginHash) + return; + + HashMap<unsigned, double>::iterator it = m_plugInAutoStartOriginHashes.find(plugInOriginHash); + if (it == m_plugInAutoStartOriginHashes.end()) + return; + if (it->value - currentTime() > plugInAutoStartExpirationTimeUpdateThreshold) + return; + + parentProcessConnection()->send(Messages::WebContext::PlugInDidReceiveUserInteraction(plugInOriginHash), 0); +} + static void fromCountedSetToHashMap(TypeCountSet* countedSet, HashMap<String, uint64_t>& map) { TypeCountSet::const_iterator end = countedSet->end(); @@ -920,12 +914,12 @@ static void fromCountedSetToHashMap(TypeCountSet* countedSet, HashMap<String, ui map.set(it->key, it->value); } -static void getWebCoreMemoryCacheStatistics(Vector<HashMap<String, uint64_t> >& result) +static void getWebCoreMemoryCacheStatistics(Vector<HashMap<String, uint64_t>>& result) { - DEFINE_STATIC_LOCAL(String, imagesString, (ASCIILiteral("Images"))); - DEFINE_STATIC_LOCAL(String, cssString, (ASCIILiteral("CSS"))); - DEFINE_STATIC_LOCAL(String, xslString, (ASCIILiteral("XSL"))); - DEFINE_STATIC_LOCAL(String, javaScriptString, (ASCIILiteral("JavaScript"))); + String imagesString(ASCIILiteral("Images")); + String cssString(ASCIILiteral("CSS")); + String xslString(ASCIILiteral("XSL")); + String javaScriptString(ASCIILiteral("JavaScript")); MemoryCache::Statistics memoryCacheStatistics = memoryCache()->getStatistics(); @@ -978,45 +972,45 @@ void WebProcess::getWebCoreStatistics(uint64_t callbackID) // Gather JavaScript statistics. { - JSLockHolder lock(JSDOMWindow::commonJSGlobalData()); - data.statisticsNumbers.set("JavaScriptObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.objectCount()); - data.statisticsNumbers.set("JavaScriptGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount()); - data.statisticsNumbers.set("JavaScriptProtectedObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount()); - data.statisticsNumbers.set("JavaScriptProtectedGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedGlobalObjectCount()); + JSLockHolder lock(JSDOMWindow::commonVM()); + data.statisticsNumbers.set(ASCIILiteral("JavaScriptObjectsCount"), JSDOMWindow::commonVM()->heap.objectCount()); + data.statisticsNumbers.set(ASCIILiteral("JavaScriptGlobalObjectsCount"), JSDOMWindow::commonVM()->heap.globalObjectCount()); + data.statisticsNumbers.set(ASCIILiteral("JavaScriptProtectedObjectsCount"), JSDOMWindow::commonVM()->heap.protectedObjectCount()); + data.statisticsNumbers.set(ASCIILiteral("JavaScriptProtectedGlobalObjectsCount"), JSDOMWindow::commonVM()->heap.protectedGlobalObjectCount()); - OwnPtr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts()); + OwnPtr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonVM()->heap.protectedObjectTypeCounts()); fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts); - OwnPtr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.objectTypeCounts()); + OwnPtr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonVM()->heap.objectTypeCounts()); fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts); - uint64_t javaScriptHeapSize = JSDOMWindow::commonJSGlobalData()->heap.size(); - data.statisticsNumbers.set("JavaScriptHeapSize", javaScriptHeapSize); - data.statisticsNumbers.set("JavaScriptFreeSize", JSDOMWindow::commonJSGlobalData()->heap.capacity() - javaScriptHeapSize); + uint64_t javaScriptHeapSize = JSDOMWindow::commonVM()->heap.size(); + data.statisticsNumbers.set(ASCIILiteral("JavaScriptHeapSize"), javaScriptHeapSize); + data.statisticsNumbers.set(ASCIILiteral("JavaScriptFreeSize"), JSDOMWindow::commonVM()->heap.capacity() - javaScriptHeapSize); } WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics(); - data.statisticsNumbers.set("FastMallocReservedVMBytes", fastMallocStatistics.reservedVMBytes); - data.statisticsNumbers.set("FastMallocCommittedVMBytes", fastMallocStatistics.committedVMBytes); - data.statisticsNumbers.set("FastMallocFreeListBytes", fastMallocStatistics.freeListBytes); + data.statisticsNumbers.set(ASCIILiteral("FastMallocReservedVMBytes"), fastMallocStatistics.reservedVMBytes); + data.statisticsNumbers.set(ASCIILiteral("FastMallocCommittedVMBytes"), fastMallocStatistics.committedVMBytes); + data.statisticsNumbers.set(ASCIILiteral("FastMallocFreeListBytes"), fastMallocStatistics.freeListBytes); // Gather icon statistics. - data.statisticsNumbers.set("IconPageURLMappingCount", iconDatabase().pageURLMappingCount()); - data.statisticsNumbers.set("IconRetainedPageURLCount", iconDatabase().retainedPageURLCount()); - data.statisticsNumbers.set("IconRecordCount", iconDatabase().iconRecordCount()); - data.statisticsNumbers.set("IconsWithDataCount", iconDatabase().iconRecordCountWithData()); + data.statisticsNumbers.set(ASCIILiteral("IconPageURLMappingCount"), iconDatabase().pageURLMappingCount()); + data.statisticsNumbers.set(ASCIILiteral("IconRetainedPageURLCount"), iconDatabase().retainedPageURLCount()); + data.statisticsNumbers.set(ASCIILiteral("IconRecordCount"), iconDatabase().iconRecordCount()); + data.statisticsNumbers.set(ASCIILiteral("IconsWithDataCount"), iconDatabase().iconRecordCountWithData()); // Gather font statistics. - data.statisticsNumbers.set("CachedFontDataCount", fontCache()->fontDataCount()); - data.statisticsNumbers.set("CachedFontDataInactiveCount", fontCache()->inactiveFontDataCount()); + data.statisticsNumbers.set(ASCIILiteral("CachedFontDataCount"), fontCache()->fontDataCount()); + data.statisticsNumbers.set(ASCIILiteral("CachedFontDataInactiveCount"), fontCache()->inactiveFontDataCount()); // Gather glyph page statistics. - data.statisticsNumbers.set("GlyphPageCount", GlyphPageTreeNode::treeGlyphPageCount()); + data.statisticsNumbers.set(ASCIILiteral("GlyphPageCount"), GlyphPageTreeNode::treeGlyphPageCount()); // Get WebCore memory cache statistics getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics); - connection()->send(Messages::WebContext::DidGetWebCoreStatistics(data, callbackID), 0); + parentProcessConnection()->send(Messages::WebContext::DidGetStatistics(data, callbackID), 0); } void WebProcess::garbageCollectJavaScriptObjects() @@ -1052,36 +1046,32 @@ void WebProcess::postInjectedBundleMessage(const CoreIPC::DataReference& message #if ENABLE(NETWORK_PROCESS) NetworkProcessConnection* WebProcess::networkConnection() { - // FIXME (NetworkProcess): How do we handle not having the connection when the WebProcess needs it? - // If the NetworkProcess crashed, for example. Do we respawn it? - ASSERT(m_networkProcessConnection); + ASSERT(m_usesNetworkProcess); + + // If we've lost our connection to the network process (e.g. it crashed) try to re-establish it. + if (!m_networkProcessConnection) + ensureNetworkProcessConnection(); + + // If we failed to re-establish it then we are beyond recovery and should crash. + if (!m_networkProcessConnection) + CRASH(); + return m_networkProcessConnection.get(); } void WebProcess::networkProcessConnectionClosed(NetworkProcessConnection* connection) { - // FIXME (NetworkProcess): How do we handle not having the connection when the WebProcess needs it? - // If the NetworkProcess crashed, for example. Do we respawn it? ASSERT(m_networkProcessConnection); ASSERT(m_networkProcessConnection == connection); m_networkProcessConnection = 0; -} - -void WebProcess::networkProcessCrashed(CoreIPC::Connection*) -{ - // FIXME (NetworkProcess): How do we handle not having the connection when the WebProcess needs it? - // If the NetworkProcess crashed, for example. Do we respawn it? - ASSERT(m_networkProcessConnection); - networkProcessConnectionClosed(m_networkProcessConnection.get()); + m_webResourceLoadScheduler->networkProcessCrashed(); } -#endif -#if ENABLE(PLUGIN_PROCESS) -void WebProcess::pluginProcessCrashed(CoreIPC::Connection*, const String& pluginPath, uint32_t processType) +WebResourceLoadScheduler& WebProcess::webResourceLoadScheduler() { - m_pluginProcessConnectionManager.pluginProcessCrashed(pluginPath, static_cast<PluginProcess::Type>(processType)); + return *m_webResourceLoadScheduler; } #endif @@ -1093,18 +1083,18 @@ void WebProcess::downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, if (initiatingPage) initiatingPage->mainFrame()->loader()->setOriginalURLForDownloadRequest(requestWithOriginalURL); - DownloadManager::shared().startDownload(downloadID, initiatingPage, requestWithOriginalURL); + downloadManager().startDownload(downloadID, requestWithOriginalURL); } void WebProcess::cancelDownload(uint64_t downloadID) { - DownloadManager::shared().cancelDownload(downloadID); + downloadManager().cancelDownload(downloadID); } #if PLATFORM(QT) void WebProcess::startTransfer(uint64_t downloadID, const String& destination) { - DownloadManager::shared().startTransfer(downloadID, destination); + downloadManager().startTransfer(downloadID, destination); } #endif @@ -1137,8 +1127,8 @@ void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState) if (!continuousSpellCheckingTurnedOff && !grammarCheckingTurnedOff) return; - HashMap<uint64_t, RefPtr<WebPage> >::iterator end = m_pageMap.end(); - for (HashMap<uint64_t, RefPtr<WebPage> >::iterator it = m_pageMap.begin(); it != end; ++it) { + HashMap<uint64_t, RefPtr<WebPage>>::iterator end = m_pageMap.end(); + for (HashMap<uint64_t, RefPtr<WebPage>>::iterator it = m_pageMap.begin(); it != end; ++it) { WebPage* page = (*it).value.get(); if (continuousSpellCheckingTurnedOff) page->unmarkAllMisspellings(); @@ -1147,26 +1137,55 @@ void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState) } } -#if ENABLE(NETSCAPE_PLUGIN_API) -void WebProcess::didGetPlugins(CoreIPC::Connection*, uint64_t requestID, const Vector<WebCore::PluginInfo>& plugins) +void WebProcess::releasePageCache() { -#if USE(PLATFORM_STRATEGIES) - // Pass this to WebPlatformStrategies.cpp. - handleDidGetPlugins(requestID, plugins); -#endif + int savedPageCacheCapacity = pageCache()->capacity(); + pageCache()->setCapacity(0); + pageCache()->setCapacity(savedPageCacheCapacity); } -#endif // ENABLE(PLUGIN_PROCESS) -#if ENABLE(CUSTOM_PROTOCOLS) -void WebProcess::registerSchemeForCustomProtocol(const WTF::String& scheme) +#if !PLATFORM(MAC) +void WebProcess::initializeProcessName(const ChildProcessInitializationParameters&) +{ +} + +void WebProcess::initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&) +{ +} + +void WebProcess::platformInitializeProcess(const ChildProcessInitializationParameters&) +{ +} + +void WebProcess::updateActivePages() +{ +} + +#endif + +void WebProcess::pageDidEnterWindow(uint64_t pageID) { - CustomProtocolManager::shared().registerScheme(scheme); + m_pagesInWindows.add(pageID); + m_nonVisibleProcessCleanupTimer.stop(); } -void WebProcess::unregisterSchemeForCustomProtocol(const WTF::String& scheme) +void WebProcess::pageWillLeaveWindow(uint64_t pageID) { - CustomProtocolManager::shared().unregisterScheme(scheme); + m_pagesInWindows.remove(pageID); + + if (m_pagesInWindows.isEmpty() && !m_nonVisibleProcessCleanupTimer.isActive()) + m_nonVisibleProcessCleanupTimer.startOneShot(nonVisibleProcessCleanupDelay); } + +void WebProcess::nonVisibleProcessCleanupTimerFired(Timer<WebProcess>*) +{ + ASSERT(m_pagesInWindows.isEmpty()); + if (!m_pagesInWindows.isEmpty()) + return; + +#if PLATFORM(MAC) + wkDestroyRenderingResources(); #endif +} } // namespace WebKit |