2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "WebProcess.h"
29 #include "AuthenticationManager.h"
30 #include "DownloadManager.h"
31 #include "InjectedBundle.h"
32 #include "InjectedBundleMessageKinds.h"
33 #include "InjectedBundleUserMessageCoders.h"
34 #include "SandboxExtension.h"
35 #include "StatisticsData.h"
36 #include "WebApplicationCacheManager.h"
37 #include "WebContextMessages.h"
38 #include "WebCookieManager.h"
39 #include "WebCoreArgumentCoders.h"
40 #include "WebDatabaseManager.h"
42 #include "WebGeolocationManagerMessages.h"
43 #include "WebKeyValueStorageManager.h"
44 #include "WebMediaCacheManager.h"
45 #include "WebMemorySampler.h"
47 #include "WebPageCreationParameters.h"
48 #include "WebPlatformStrategies.h"
49 #include "WebPreferencesStore.h"
50 #include "WebProcessCreationParameters.h"
51 #include "WebProcessMessages.h"
52 #include "WebProcessProxyMessages.h"
53 #include "WebResourceCacheManager.h"
54 #include <JavaScriptCore/JSLock.h>
55 #include <JavaScriptCore/MemoryStatistics.h>
56 #include <WebCore/AXObjectCache.h>
57 #include <WebCore/ApplicationCacheStorage.h>
58 #include <WebCore/CrossOriginPreflightResultCache.h>
59 #include <WebCore/Font.h>
60 #include <WebCore/FontCache.h>
61 #include <WebCore/Frame.h>
62 #include <WebCore/GCController.h>
63 #include <WebCore/GlyphPageTreeNode.h>
64 #include <WebCore/IconDatabase.h>
65 #include <WebCore/JSDOMWindow.h>
66 #include <WebCore/Language.h>
67 #include <WebCore/Logging.h>
68 #include <WebCore/MemoryCache.h>
69 #include <WebCore/MemoryPressureHandler.h>
70 #include <WebCore/Page.h>
71 #include <WebCore/PageCache.h>
72 #include <WebCore/PageGroup.h>
73 #include <WebCore/ResourceHandle.h>
74 #include <WebCore/RunLoop.h>
75 #include <WebCore/SchemeRegistry.h>
76 #include <WebCore/SecurityOrigin.h>
77 #include <WebCore/Settings.h>
78 #include <WebCore/StorageTracker.h>
79 #include <wtf/HashCountedSet.h>
80 #include <wtf/PassRefPtr.h>
81 #include <wtf/RandomNumber.h>
83 #if ENABLE(NETWORK_INFO)
84 #include "WebNetworkInfoManagerMessages.h"
91 #if !ENABLE(PLUGIN_PROCESS)
92 #include "NetscapePluginModule.h"
95 #if ENABLE(TIZEN_FILE_SYSTEM)
96 #include "FileSystem.h"
97 #include "WebLocalFileSystemManager.h"
98 #include <WebCore/LocalFileSystem.h>
101 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
102 #include "WebPage/efl/tizen/PlatformSurfacePoolTizen.h"
105 #if ENABLE(TIZEN_LOG)
109 #if ENABLE(TIZEN_EXTENSIBLE_API)
110 #include <WebCore/TizenExtensibleAPI.h>
114 using namespace WebCore;
119 static void sleep(unsigned seconds)
121 ::Sleep(seconds * 1000);
125 static void randomCrashThread(void*) NO_RETURN_DUE_TO_CRASH;
126 void randomCrashThread(void*)
128 // This delay was chosen semi-arbitrarily. We want the crash to happen somewhat quickly to
129 // enable useful stress testing, but not so quickly that the web process will always crash soon
131 static const unsigned maximumRandomCrashDelay = 180;
133 sleep(randomNumber() * maximumRandomCrashDelay);
137 static void startRandomCrashThreadIfRequested()
139 if (!getenv("WEBKIT2_CRASH_WEB_PROCESS_RANDOMLY"))
141 createThread(randomCrashThread, 0, "WebKit2: Random Crash Thread");
144 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
145 WebProcess::WaitForJavaScriptPopupFinished::WaitForJavaScriptPopupFinished()
147 ++WebProcess::shared().m_isWaitingForJavaScriptPopupCount;
150 WebProcess::WaitForJavaScriptPopupFinished::~WaitForJavaScriptPopupFinished()
152 --WebProcess::shared().m_isWaitingForJavaScriptPopupCount;
155 bool WebProcess::isWaitingForJavaScriptPopupFinished()
157 return m_isWaitingForJavaScriptPopupCount > 0;
161 WebProcess& WebProcess::shared()
163 static WebProcess& process = *new WebProcess;
167 static const double shutdownTimeout = 60;
169 WebProcess::WebProcess()
170 : ChildProcess(shutdownTimeout)
171 , m_inDidClose(false)
172 , m_shouldTrackVisitedLinks(true)
173 , m_hasSetCacheModel(false)
174 , m_cacheModel(CacheModelDocumentViewer)
175 #if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC)
176 , m_compositingRenderServerPort(MACH_PORT_NULL)
179 , m_clearResourceCachesDispatchGroup(0)
181 , m_fullKeyboardAccessEnabled(false)
183 , m_networkAccessManager(0)
185 , m_textCheckerState()
186 , m_geolocationManager(this)
187 #if ENABLE(BATTERY_STATUS)
188 , m_batteryManager(this)
190 #if ENABLE(NETWORK_INFO)
191 , m_networkInfoManager(this)
193 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
194 , m_notificationManager(this)
196 , m_iconDatabaseProxy(this)
197 #if ENABLE(PLUGIN_PROCESS)
198 , m_disablePluginProcessMessageTimeout(false)
201 , m_soupRequestManager(this)
203 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
204 , m_isWaitingForJavaScriptPopupCount(0)
206 #if ENABLE(TIZEN_WEBKIT2_MEMORY_SAVING_MODE)
207 , m_memorySavingModeEnabled(false)
210 #if USE(PLATFORM_STRATEGIES)
211 // Initialize our platform strategies.
212 WebPlatformStrategies::initialize();
213 #endif // USE(PLATFORM_STRATEGIES)
215 #if !LOG_DISABLED && ENABLE(TIZEN_LOG)
216 WebKit::initializeLogChannelsIfNecessary();
220 WebCore::initializeLoggingChannelsIfNecessary();
221 #endif // !LOG_DISABLED
224 void WebProcess::initialize(CoreIPC::Connection::Identifier serverIdentifier, RunLoop* runLoop)
226 ASSERT(!m_connection);
228 m_connection = WebConnectionToUIProcess::create(this, serverIdentifier, runLoop);
230 m_connection->connection()->addQueueClient(&m_eventDispatcher);
231 m_connection->connection()->addQueueClient(this);
233 m_connection->connection()->open();
236 #if PLATFORM(EFL) && OS(TIZEN)
237 // If OnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage is false,
238 // DecidePolicyFornavigationAction(Sync message) can be processed
239 // before processing DidCreateSubframe(non sync message) and WebProcess will be crashed.
240 connection()->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true);
243 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
244 m_platformSurfacePool = adoptPtr(new PlatformSurfacePoolTizen());
247 #if ENABLE(TIZEN_JPEGIMAGE_DECODING_THREAD)
248 WebCore::AsyncImageDecoder::sharedAsyncImageDecoder();
251 startRandomCrashThreadIfRequested();
254 void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder* arguments)
256 ASSERT(m_pageMap.isEmpty());
258 platformInitializeWebProcess(parameters, arguments);
260 memoryPressureHandler().install();
262 RefPtr<APIObject> injectedBundleInitializationUserData;
263 InjectedBundleUserMessageDecoder messageDecoder(injectedBundleInitializationUserData);
264 if (!arguments->decode(messageDecoder))
267 if (!parameters.injectedBundlePath.isEmpty()) {
268 m_injectedBundle = InjectedBundle::create(parameters.injectedBundlePath);
269 m_injectedBundle->setSandboxExtension(SandboxExtension::create(parameters.injectedBundlePathExtensionHandle));
271 if (!m_injectedBundle->load(injectedBundleInitializationUserData.get())) {
272 // Don't keep around the InjectedBundle reference if the load fails.
273 m_injectedBundle.clear();
277 #if ENABLE(SQL_DATABASE)
278 // Make sure the WebDatabaseManager is initialized so that the Database directory is set.
279 WebDatabaseManager::initialize(parameters.databaseDirectory);
282 #if ENABLE(ICONDATABASE)
283 m_iconDatabaseProxy.setEnabled(parameters.iconDatabaseEnabled);
286 #if ENABLE(TIZEN_FILE_SYSTEM)
287 if (WebCore::makeAllDirectories(parameters.localFileSystemDirectory))
288 WebCore::LocalFileSystem::initializeLocalFileSystem(parameters.localFileSystemDirectory);
291 StorageTracker::initializeTracker(parameters.localStorageDirectory, &WebKeyValueStorageManager::shared());
292 m_localStorageDirectory = parameters.localStorageDirectory;
294 if (!parameters.applicationCacheDirectory.isEmpty())
295 cacheStorage().setCacheDirectory(parameters.applicationCacheDirectory);
297 #if ENABLE(TIZEN_WEBKIT2_VISITED_LINKS)
298 setShouldTrackVisitedLinks(true);
300 setShouldTrackVisitedLinks(parameters.shouldTrackVisitedLinks);
302 setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
304 if (!parameters.languages.isEmpty())
305 overrideUserPreferredLanguages(parameters.languages);
307 m_textCheckerState = parameters.textCheckerState;
309 m_fullKeyboardAccessEnabled = parameters.fullKeyboardAccessEnabled;
311 for (size_t i = 0; i < parameters.urlSchemesRegistererdAsEmptyDocument.size(); ++i)
312 registerURLSchemeAsEmptyDocument(parameters.urlSchemesRegistererdAsEmptyDocument[i]);
314 for (size_t i = 0; i < parameters.urlSchemesRegisteredAsSecure.size(); ++i)
315 registerURLSchemeAsSecure(parameters.urlSchemesRegisteredAsSecure[i]);
317 for (size_t i = 0; i < parameters.urlSchemesForWhichDomainRelaxationIsForbidden.size(); ++i)
318 setDomainRelaxationForbiddenForURLScheme(parameters.urlSchemesForWhichDomainRelaxationIsForbidden[i]);
320 setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval);
322 for (size_t i = 0; i < parameters.mimeTypesWithCustomRepresentation.size(); ++i)
323 m_mimeTypesWithCustomRepresentations.add(parameters.mimeTypesWithCustomRepresentation[i]);
326 m_presenterApplicationPid = parameters.presenterApplicationPid;
329 if (parameters.shouldAlwaysUseComplexTextCodePath)
330 setAlwaysUsesComplexTextCodePath(true);
332 if (parameters.shouldUseFontSmoothing)
333 setShouldUseFontSmoothing(true);
335 #if USE(CFURLSTORAGESESSIONS)
336 WebCore::ResourceHandle::setPrivateBrowsingStorageSessionIdentifierBase(parameters.uiProcessBundleIdentifier);
339 #if ENABLE(PLUGIN_PROCESS)
340 m_disablePluginProcessMessageTimeout = parameters.disablePluginProcessMessageTimeout;
343 #if ENABLE(TIZEN_INDEXED_DATABASE)
344 m_indexedDatabaseDirectory = parameters.indexedDatabaseDirectory;
347 #if ENABLE(TIZEN_EXTENSIBLE_API)
348 TizenExtensibleAPI::initializeTizenExtensibleAPI();
352 void WebProcess::setShouldTrackVisitedLinks(bool shouldTrackVisitedLinks)
354 m_shouldTrackVisitedLinks = shouldTrackVisitedLinks;
355 PageGroup::setShouldTrackVisitedLinks(shouldTrackVisitedLinks);
358 void WebProcess::registerURLSchemeAsEmptyDocument(const String& urlScheme)
360 SchemeRegistry::registerURLSchemeAsEmptyDocument(urlScheme);
363 void WebProcess::registerURLSchemeAsSecure(const String& urlScheme) const
365 SchemeRegistry::registerURLSchemeAsSecure(urlScheme);
368 void WebProcess::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) const
370 SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(true, urlScheme);
373 void WebProcess::setDefaultRequestTimeoutInterval(double timeoutInterval)
375 ResourceRequest::setDefaultTimeoutInterval(timeoutInterval);
378 void WebProcess::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
380 WebCore::Font::setCodePath(alwaysUseComplexText ? WebCore::Font::Complex : WebCore::Font::Auto);
383 void WebProcess::setShouldUseFontSmoothing(bool useFontSmoothing)
385 WebCore::Font::setShouldUseSmoothing(useFontSmoothing);
388 void WebProcess::userPreferredLanguagesChanged(const Vector<String>& languages) const
390 overrideUserPreferredLanguages(languages);
393 void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
395 m_fullKeyboardAccessEnabled = fullKeyboardAccessEnabled;
398 void WebProcess::setVisitedLinkTable(const SharedMemory::Handle& handle)
400 RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly);
404 m_visitedLinkTable.setSharedMemory(sharedMemory.release());
407 void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes)
409 // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext.
410 for (size_t i = 0; i < linkHashes.size(); ++i) {
411 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin();
412 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end();
413 for (; it != end; ++it)
414 Page::visitedStateChanged(PageGroup::pageGroup(it->second->identifier()), linkHashes[i]);
417 pageCache()->markPagesForVistedLinkStyleRecalc();
420 void WebProcess::allVisitedLinkStateChanged()
422 // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext.
423 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin();
424 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end();
425 for (; it != end; ++it)
426 Page::allVisitedStateChanged(PageGroup::pageGroup(it->second->identifier()));
428 pageCache()->markPagesForVistedLinkStyleRecalc();
431 bool WebProcess::isLinkVisited(LinkHash linkHash) const
433 return m_visitedLinkTable.isLinkVisited(linkHash);
436 void WebProcess::addVisitedLink(WebCore::LinkHash linkHash)
438 if (isLinkVisited(linkHash) || !m_shouldTrackVisitedLinks)
440 connection()->send(Messages::WebContext::AddVisitedLinkHash(linkHash), 0);
443 void WebProcess::setCacheModel(uint32_t cm)
445 CacheModel cacheModel = static_cast<CacheModel>(cm);
447 if (!m_hasSetCacheModel || cacheModel != m_cacheModel) {
448 m_hasSetCacheModel = true;
449 m_cacheModel = cacheModel;
450 platformSetCacheModel(cacheModel);
454 #if ENABLE(TIZEN_CACHE_CONTROL)
455 void WebProcess::setCacheDisabled(bool cacheDisabled)
457 platformSetCacheDisabled(cacheDisabled);
461 void WebProcess::calculateCacheSizes(CacheModel cacheModel, uint64_t memorySize, uint64_t diskFreeSize,
462 unsigned& cacheTotalCapacity, unsigned& cacheMinDeadCapacity, unsigned& cacheMaxDeadCapacity, double& deadDecodedDataDeletionInterval,
463 unsigned& pageCacheCapacity, unsigned long& urlCacheMemoryCapacity, unsigned long& urlCacheDiskCapacity)
465 switch (cacheModel) {
466 case CacheModelDocumentViewer: {
467 // Page cache capacity (in pages)
468 pageCacheCapacity = 0;
470 // Object cache capacities (in bytes)
471 if (memorySize >= 2048)
472 cacheTotalCapacity = 96 * 1024 * 1024;
473 else if (memorySize >= 1536)
474 cacheTotalCapacity = 64 * 1024 * 1024;
475 else if (memorySize >= 1024)
476 cacheTotalCapacity = 32 * 1024 * 1024;
477 else if (memorySize >= 512)
478 cacheTotalCapacity = 16 * 1024 * 1024;
480 cacheMinDeadCapacity = 0;
481 cacheMaxDeadCapacity = 0;
483 // Foundation memory cache capacity (in bytes)
484 urlCacheMemoryCapacity = 0;
486 // Foundation disk cache capacity (in bytes)
487 urlCacheDiskCapacity = 0;
491 case CacheModelDocumentBrowser: {
492 // Page cache capacity (in pages)
493 if (memorySize >= 1024)
494 pageCacheCapacity = 3;
495 else if (memorySize >= 512)
496 pageCacheCapacity = 2;
497 else if (memorySize >= 256)
498 pageCacheCapacity = 1;
500 pageCacheCapacity = 0;
502 // Object cache capacities (in bytes)
503 if (memorySize >= 2048)
504 cacheTotalCapacity = 96 * 1024 * 1024;
505 else if (memorySize >= 1536)
506 cacheTotalCapacity = 64 * 1024 * 1024;
507 else if (memorySize >= 1024)
508 cacheTotalCapacity = 32 * 1024 * 1024;
509 else if (memorySize >= 512)
510 cacheTotalCapacity = 16 * 1024 * 1024;
512 cacheMinDeadCapacity = cacheTotalCapacity / 8;
513 cacheMaxDeadCapacity = cacheTotalCapacity / 4;
515 // Foundation memory cache capacity (in bytes)
516 if (memorySize >= 2048)
517 urlCacheMemoryCapacity = 4 * 1024 * 1024;
518 else if (memorySize >= 1024)
519 urlCacheMemoryCapacity = 2 * 1024 * 1024;
520 else if (memorySize >= 512)
521 urlCacheMemoryCapacity = 1 * 1024 * 1024;
523 urlCacheMemoryCapacity = 512 * 1024;
525 // Foundation disk cache capacity (in bytes)
526 if (diskFreeSize >= 16384)
527 urlCacheDiskCapacity = 50 * 1024 * 1024;
528 else if (diskFreeSize >= 8192)
529 urlCacheDiskCapacity = 40 * 1024 * 1024;
530 else if (diskFreeSize >= 4096)
531 urlCacheDiskCapacity = 30 * 1024 * 1024;
533 urlCacheDiskCapacity = 20 * 1024 * 1024;
537 case CacheModelPrimaryWebBrowser: {
538 // Page cache capacity (in pages)
539 // (Research indicates that value / page drops substantially after 3 pages.)
540 if (memorySize >= 2048)
541 pageCacheCapacity = 5;
542 else if (memorySize >= 1024)
543 pageCacheCapacity = 4;
544 else if (memorySize >= 512)
545 pageCacheCapacity = 3;
546 else if (memorySize >= 256)
547 pageCacheCapacity = 2;
549 pageCacheCapacity = 1;
551 // Object cache capacities (in bytes)
552 // (Testing indicates that value / MB depends heavily on content and
553 // browsing pattern. Even growth above 128MB can have substantial
554 // value / MB for some content / browsing patterns.)
555 if (memorySize >= 2048)
556 cacheTotalCapacity = 128 * 1024 * 1024;
557 else if (memorySize >= 1536)
558 cacheTotalCapacity = 96 * 1024 * 1024;
559 else if (memorySize >= 1024)
560 cacheTotalCapacity = 64 * 1024 * 1024;
561 else if (memorySize >= 512)
562 cacheTotalCapacity = 32 * 1024 * 1024;
564 cacheMinDeadCapacity = cacheTotalCapacity / 4;
565 cacheMaxDeadCapacity = cacheTotalCapacity / 2;
567 // This code is here to avoid a PLT regression. We can remove it if we
568 // can prove that the overall system gain would justify the regression.
569 cacheMaxDeadCapacity = std::max(24u, cacheMaxDeadCapacity);
571 deadDecodedDataDeletionInterval = 60;
573 // Foundation memory cache capacity (in bytes)
574 // (These values are small because WebCore does most caching itself.)
575 if (memorySize >= 1024)
576 urlCacheMemoryCapacity = 4 * 1024 * 1024;
577 else if (memorySize >= 512)
578 urlCacheMemoryCapacity = 2 * 1024 * 1024;
579 else if (memorySize >= 256)
580 urlCacheMemoryCapacity = 1 * 1024 * 1024;
582 urlCacheMemoryCapacity = 512 * 1024;
584 // Foundation disk cache capacity (in bytes)
585 if (diskFreeSize >= 16384)
586 urlCacheDiskCapacity = 175 * 1024 * 1024;
587 else if (diskFreeSize >= 8192)
588 urlCacheDiskCapacity = 150 * 1024 * 1024;
589 else if (diskFreeSize >= 4096)
590 urlCacheDiskCapacity = 125 * 1024 * 1024;
591 else if (diskFreeSize >= 2048)
592 urlCacheDiskCapacity = 100 * 1024 * 1024;
593 else if (diskFreeSize >= 1024)
594 urlCacheDiskCapacity = 75 * 1024 * 1024;
596 urlCacheDiskCapacity = 50 * 1024 * 1024;
601 ASSERT_NOT_REACHED();
605 WebPage* WebProcess::focusedWebPage() const
607 HashMap<uint64_t, RefPtr<WebPage> >::const_iterator end = m_pageMap.end();
608 for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator it = m_pageMap.begin(); it != end; ++it) {
609 WebPage* page = (*it).second.get();
610 if (page->windowAndWebPageAreFocused())
616 WebPage* WebProcess::webPage(uint64_t pageID) const
618 return m_pageMap.get(pageID).get();
621 void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
623 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
624 if (!m_platformSurfacePool)
625 m_platformSurfacePool = adoptPtr(new PlatformSurfacePoolTizen());
627 // It is necessary to check for page existence here since during a window.open() (or targeted
628 // link) the WebPage gets created both in the synchronous handler and through the normal way.
629 HashMap<uint64_t, RefPtr<WebPage> >::AddResult result = m_pageMap.add(pageID, 0);
630 if (result.isNewEntry) {
631 ASSERT(!result.iterator->second);
632 result.iterator->second = WebPage::create(pageID, parameters);
634 // Balanced by an enableTermination in removeWebPage.
635 disableTermination();
638 ASSERT(result.iterator->second);
641 void WebProcess::removeWebPage(uint64_t pageID)
643 ASSERT(m_pageMap.contains(pageID));
645 m_pageMap.remove(pageID);
647 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
648 if (m_pageMap.size() == 0)
649 m_platformSurfacePool = nullptr;
655 bool WebProcess::isSeparateProcess() const
657 // If we're running on the main run loop, we assume that we're in a separate process.
658 return m_runLoop == RunLoop::main();
661 bool WebProcess::shouldTerminate()
663 // Keep running forever if we're running in the same process.
664 if (!isSeparateProcess())
667 ASSERT(m_pageMap.isEmpty());
668 ASSERT(!DownloadManager::shared().isDownloading());
670 // FIXME: the ShouldTerminate message should also send termination parameters, such as any session cookies that need to be preserved.
671 bool shouldTerminate = false;
672 if (connection()->sendSync(Messages::WebProcessProxy::ShouldTerminate(), Messages::WebProcessProxy::ShouldTerminate::Reply(shouldTerminate), 0)
679 void WebProcess::terminate()
682 gcController().garbageCollectNow();
683 memoryCache()->setDisabled(true);
686 // Invalidate our connection.
687 m_connection->invalidate();
688 m_connection = nullptr;
694 void WebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply)
696 #if ENABLE(TIZEN_NOTIFICATIONS)
697 if (messageID.is<CoreIPC::MessageClassWebNotificationManager>()) {
698 m_notificationManager.didReceiveSyncMessage(connection, messageID, arguments, reply);
703 #if ENABLE(TIZEN_CACHE_DUMP_SYNC)
704 if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) {
705 WebResourceCacheManager::shared().didReceiveSyncMessage(connection, messageID, arguments, reply);
710 uint64_t pageID = arguments->destinationID();
714 WebPage* page = webPage(pageID);
718 page->didReceiveSyncMessage(connection, messageID, arguments, reply);
721 void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
723 if (messageID.is<CoreIPC::MessageClassWebProcess>()) {
724 didReceiveWebProcessMessage(connection, messageID, arguments);
728 if (messageID.is<CoreIPC::MessageClassAuthenticationManager>()) {
729 AuthenticationManager::shared().didReceiveMessage(connection, messageID, arguments);
733 if (messageID.is<CoreIPC::MessageClassWebApplicationCacheManager>()) {
734 WebApplicationCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
738 if (messageID.is<CoreIPC::MessageClassWebCookieManager>()) {
739 WebCookieManager::shared().didReceiveMessage(connection, messageID, arguments);
743 #if ENABLE(SQL_DATABASE)
744 if (messageID.is<CoreIPC::MessageClassWebDatabaseManager>()) {
745 WebDatabaseManager::shared().didReceiveMessage(connection, messageID, arguments);
750 if (messageID.is<CoreIPC::MessageClassWebGeolocationManager>()) {
751 m_geolocationManager.didReceiveMessage(connection, messageID, arguments);
755 #if ENABLE(BATTERY_STATUS)
756 if (messageID.is<CoreIPC::MessageClassWebBatteryManager>()) {
757 m_batteryManager.didReceiveMessage(connection, messageID, arguments);
762 #if ENABLE(NETWORK_INFO)
763 if (messageID.is<CoreIPC::MessageClassWebNetworkInfoManager>()) {
764 m_networkInfoManager.didReceiveMessage(connection, messageID, arguments);
769 if (messageID.is<CoreIPC::MessageClassWebIconDatabaseProxy>()) {
770 m_iconDatabaseProxy.didReceiveMessage(connection, messageID, arguments);
774 if (messageID.is<CoreIPC::MessageClassWebKeyValueStorageManager>()) {
775 WebKeyValueStorageManager::shared().didReceiveMessage(connection, messageID, arguments);
779 #if ENABLE(TIZEN_FILE_SYSTEM)
780 if (messageID.is<CoreIPC::MessageClassWebLocalFileSystemManager>()) {
781 WebLocalFileSystemManager::shared().didReceiveMessage(connection, messageID, arguments);
786 if (messageID.is<CoreIPC::MessageClassWebMediaCacheManager>()) {
787 WebMediaCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
791 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
792 if (messageID.is<CoreIPC::MessageClassWebNotificationManager>()) {
793 m_notificationManager.didReceiveMessage(connection, messageID, arguments);
798 if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) {
799 WebResourceCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
804 if (messageID.is<CoreIPC::MessageClassWebSoupRequestManager>()) {
805 m_soupRequestManager.didReceiveMessage(connection, messageID, arguments);
810 if (messageID.is<CoreIPC::MessageClassInjectedBundle>()) {
811 if (!m_injectedBundle)
813 m_injectedBundle->didReceiveMessage(connection, messageID, arguments);
817 uint64_t pageID = arguments->destinationID();
821 WebPage* page = webPage(pageID);
825 page->didReceiveMessage(connection, messageID, arguments);
828 void WebProcess::didClose(CoreIPC::Connection*)
830 // When running in the same process the connection will never be closed.
831 ASSERT(isSeparateProcess());
836 // Close all the live pages.
837 Vector<RefPtr<WebPage> > pages;
838 copyValuesToVector(m_pageMap, pages);
839 for (size_t i = 0; i < pages.size(); ++i)
843 gcController().garbageCollectSoon();
844 memoryCache()->setDisabled(true);
847 // The UI process closed this connection, shut down.
851 void WebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID)
853 // We received an invalid message, but since this is from the UI process (which we trust),
854 // we'll let it slide.
857 void WebProcess::syncMessageSendTimedOut(CoreIPC::Connection*)
861 void WebProcess::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage)
863 if (messageID.is<CoreIPC::MessageClassWebProcess>()) {
864 didReceiveWebProcessMessageOnConnectionWorkQueue(connection, messageID, arguments, didHandleMessage);
869 WebFrame* WebProcess::webFrame(uint64_t frameID) const
871 return m_frameMap.get(frameID);
874 void WebProcess::addWebFrame(uint64_t frameID, WebFrame* frame)
876 m_frameMap.set(frameID, frame);
879 void WebProcess::removeWebFrame(uint64_t frameID)
881 m_frameMap.remove(frameID);
883 // We can end up here after our connection has closed when WebCore's frame life-support timer
884 // fires when the application is shutting down. There's no need (and no way) to update the UI
885 // process in this case.
889 connection()->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0);
892 WebPageGroupProxy* WebProcess::webPageGroup(uint64_t pageGroupID)
894 return m_pageGroupMap.get(pageGroupID).get();
897 WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupData)
899 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::AddResult result = m_pageGroupMap.add(pageGroupData.pageGroupID, 0);
900 if (result.isNewEntry) {
901 ASSERT(!result.iterator->second);
902 result.iterator->second = WebPageGroupProxy::create(pageGroupData);
905 return result.iterator->second.get();
908 static bool canPluginHandleResponse(const ResourceResponse& response)
913 if (!WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPluginPath(response.mimeType(), response.url().string()), Messages::WebContext::GetPluginPath::Reply(pluginPath, blocked), 0))
916 return !blocked && !pluginPath.isEmpty();
919 bool WebProcess::shouldUseCustomRepresentationForResponse(const ResourceResponse& response) const
921 if (!m_mimeTypesWithCustomRepresentations.contains(response.mimeType()))
924 // If a plug-in exists that claims to support this response, it should take precedence over the custom representation.
925 return !canPluginHandleResponse(response);
928 void WebProcess::clearResourceCaches(ResourceCachesToClear resourceCachesToClear)
930 #if ENABLE(TIZEN_CACHE_MEMORY_OPTIMIZATION)
931 if(resourceCachesToClear == InDecodedDataResourceCachesOnly) {
932 memoryCache()->removeAllDecodedData();
937 platformClearResourceCaches(resourceCachesToClear);
939 // Toggling the cache model like this forces the cache to evict all its in-memory resources.
940 // FIXME: We need a better way to do this.
941 CacheModel cacheModel = m_cacheModel;
942 setCacheModel(CacheModelDocumentViewer);
943 setCacheModel(cacheModel);
945 memoryCache()->evictResources();
947 // Empty the cross-origin preflight cache.
948 CrossOriginPreflightResultCache::shared().empty();
951 #if ENABLE(TIZEN_CACHE_DUMP_SYNC)
952 void WebProcess::dumpResourceCaches()
954 platformDumpResourceCaches();
958 void WebProcess::clearApplicationCache()
960 // Empty the application cache.
961 cacheStorage().empty();
964 #if !ENABLE(PLUGIN_PROCESS)
965 void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint64_t callbackID)
967 LocalTerminationDisabler terminationDisabler(*this);
969 HashSet<String> sitesSet;
971 #if ENABLE(NETSCAPE_PLUGIN_API)
972 for (size_t i = 0; i < pluginPaths.size(); ++i) {
973 RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]);
974 if (!netscapePluginModule)
977 Vector<String> sites = netscapePluginModule->sitesWithData();
978 for (size_t i = 0; i < sites.size(); ++i)
979 sitesSet.add(sites[i]);
983 Vector<String> sites;
984 copyToVector(sitesSet, sites);
986 connection()->send(Messages::WebContext::DidGetSitesWithPluginData(sites, callbackID), 0);
989 void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID)
991 LocalTerminationDisabler terminationDisabler(*this);
993 #if ENABLE(NETSCAPE_PLUGIN_API)
994 for (size_t i = 0; i < pluginPaths.size(); ++i) {
995 RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]);
996 if (!netscapePluginModule)
999 if (sites.isEmpty()) {
1000 // Clear everything.
1001 netscapePluginModule->clearSiteData(String(), flags, maxAgeInSeconds);
1005 for (size_t i = 0; i < sites.size(); ++i)
1006 netscapePluginModule->clearSiteData(sites[i], flags, maxAgeInSeconds);
1010 connection()->send(Messages::WebContext::DidClearPluginSiteData(callbackID), 0);
1014 static void fromCountedSetToHashMap(TypeCountSet* countedSet, HashMap<String, uint64_t>& map)
1016 TypeCountSet::const_iterator end = countedSet->end();
1017 for (TypeCountSet::const_iterator it = countedSet->begin(); it != end; ++it)
1018 map.set(it->first, it->second);
1021 static void getWebCoreMemoryCacheStatistics(Vector<HashMap<String, uint64_t> >& result)
1023 DEFINE_STATIC_LOCAL(String, imagesString, ("Images"));
1024 DEFINE_STATIC_LOCAL(String, cssString, ("CSS"));
1025 DEFINE_STATIC_LOCAL(String, xslString, ("XSL"));
1026 DEFINE_STATIC_LOCAL(String, javaScriptString, ("JavaScript"));
1028 MemoryCache::Statistics memoryCacheStatistics = memoryCache()->getStatistics();
1030 HashMap<String, uint64_t> counts;
1031 counts.set(imagesString, memoryCacheStatistics.images.count);
1032 counts.set(cssString, memoryCacheStatistics.cssStyleSheets.count);
1033 counts.set(xslString, memoryCacheStatistics.xslStyleSheets.count);
1034 counts.set(javaScriptString, memoryCacheStatistics.scripts.count);
1035 result.append(counts);
1037 HashMap<String, uint64_t> sizes;
1038 sizes.set(imagesString, memoryCacheStatistics.images.size);
1039 sizes.set(cssString, memoryCacheStatistics.cssStyleSheets.size);
1040 sizes.set(xslString, memoryCacheStatistics.xslStyleSheets.size);
1041 sizes.set(javaScriptString, memoryCacheStatistics.scripts.size);
1042 result.append(sizes);
1044 HashMap<String, uint64_t> liveSizes;
1045 liveSizes.set(imagesString, memoryCacheStatistics.images.liveSize);
1046 liveSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.liveSize);
1047 liveSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.liveSize);
1048 liveSizes.set(javaScriptString, memoryCacheStatistics.scripts.liveSize);
1049 result.append(liveSizes);
1051 HashMap<String, uint64_t> decodedSizes;
1052 decodedSizes.set(imagesString, memoryCacheStatistics.images.decodedSize);
1053 decodedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.decodedSize);
1054 decodedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.decodedSize);
1055 decodedSizes.set(javaScriptString, memoryCacheStatistics.scripts.decodedSize);
1056 result.append(decodedSizes);
1058 HashMap<String, uint64_t> purgeableSizes;
1059 purgeableSizes.set(imagesString, memoryCacheStatistics.images.purgeableSize);
1060 purgeableSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgeableSize);
1061 purgeableSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgeableSize);
1062 purgeableSizes.set(javaScriptString, memoryCacheStatistics.scripts.purgeableSize);
1063 result.append(purgeableSizes);
1065 HashMap<String, uint64_t> purgedSizes;
1066 purgedSizes.set(imagesString, memoryCacheStatistics.images.purgedSize);
1067 purgedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgedSize);
1068 purgedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgedSize);
1069 purgedSizes.set(javaScriptString, memoryCacheStatistics.scripts.purgedSize);
1070 result.append(purgedSizes);
1073 void WebProcess::getWebCoreStatistics(uint64_t callbackID)
1075 StatisticsData data;
1077 // Gather JavaScript statistics.
1079 JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
1080 data.statisticsNumbers.set("JavaScriptObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.objectCount());
1081 data.statisticsNumbers.set("JavaScriptGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount());
1082 data.statisticsNumbers.set("JavaScriptProtectedObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount());
1083 data.statisticsNumbers.set("JavaScriptProtectedGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedGlobalObjectCount());
1085 OwnPtr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts());
1086 fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts);
1088 OwnPtr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.objectTypeCounts());
1089 fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts);
1091 uint64_t javaScriptHeapSize = JSDOMWindow::commonJSGlobalData()->heap.size();
1092 data.statisticsNumbers.set("JavaScriptHeapSize", javaScriptHeapSize);
1093 data.statisticsNumbers.set("JavaScriptFreeSize", JSDOMWindow::commonJSGlobalData()->heap.capacity() - javaScriptHeapSize);
1096 WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics();
1097 data.statisticsNumbers.set("FastMallocReservedVMBytes", fastMallocStatistics.reservedVMBytes);
1098 data.statisticsNumbers.set("FastMallocCommittedVMBytes", fastMallocStatistics.committedVMBytes);
1099 data.statisticsNumbers.set("FastMallocFreeListBytes", fastMallocStatistics.freeListBytes);
1101 // Gather icon statistics.
1102 data.statisticsNumbers.set("IconPageURLMappingCount", iconDatabase().pageURLMappingCount());
1103 data.statisticsNumbers.set("IconRetainedPageURLCount", iconDatabase().retainedPageURLCount());
1104 data.statisticsNumbers.set("IconRecordCount", iconDatabase().iconRecordCount());
1105 data.statisticsNumbers.set("IconsWithDataCount", iconDatabase().iconRecordCountWithData());
1107 // Gather font statistics.
1108 data.statisticsNumbers.set("CachedFontDataCount", fontCache()->fontDataCount());
1109 data.statisticsNumbers.set("CachedFontDataInactiveCount", fontCache()->inactiveFontDataCount());
1111 // Gather glyph page statistics.
1112 #if !(PLATFORM(QT) && !HAVE(QRAWFONT)) // Qt doesn't use the glyph page tree currently. See: bug 63467.
1113 data.statisticsNumbers.set("GlyphPageCount", GlyphPageTreeNode::treeGlyphPageCount());
1116 // Get WebCore memory cache statistics
1117 getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics);
1119 connection()->send(Messages::WebContext::DidGetWebCoreStatistics(data, callbackID), 0);
1122 void WebProcess::garbageCollectJavaScriptObjects()
1124 gcController().garbageCollectNow();
1127 void WebProcess::setJavaScriptGarbageCollectorTimerEnabled(bool flag)
1129 gcController().setJavaScriptGarbageCollectorTimerEnabled(flag);
1132 #if ENABLE(PLUGIN_PROCESS)
1133 void WebProcess::pluginProcessCrashed(CoreIPC::Connection*, const String& pluginPath)
1135 m_pluginProcessConnectionManager.pluginProcessCrashed(pluginPath);
1139 void WebProcess::downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, const ResourceRequest& request)
1141 WebPage* initiatingPage = initiatingPageID ? webPage(initiatingPageID) : 0;
1143 ResourceRequest requestWithOriginalURL = request;
1145 initiatingPage->mainFrame()->loader()->setOriginalURLForDownloadRequest(requestWithOriginalURL);
1147 DownloadManager::shared().startDownload(downloadID, initiatingPage, requestWithOriginalURL);
1150 void WebProcess::cancelDownload(uint64_t downloadID)
1152 DownloadManager::shared().cancelDownload(downloadID);
1156 void WebProcess::startTransfer(uint64_t downloadID, const String& destination)
1158 DownloadManager::shared().startTransfer(downloadID, destination);
1162 void WebProcess::setEnhancedAccessibility(bool flag)
1164 WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility(flag);
1167 void WebProcess::startMemorySampler(const SandboxExtension::Handle& sampleLogFileHandle, const String& sampleLogFilePath, const double interval)
1169 #if ENABLE(MEMORY_SAMPLER)
1170 WebMemorySampler::shared()->start(sampleLogFileHandle, sampleLogFilePath, interval);
1174 void WebProcess::stopMemorySampler()
1176 #if ENABLE(MEMORY_SAMPLER)
1177 WebMemorySampler::shared()->stop();
1181 void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState)
1183 bool continuousSpellCheckingTurnedOff = !textCheckerState.isContinuousSpellCheckingEnabled && m_textCheckerState.isContinuousSpellCheckingEnabled;
1184 bool grammarCheckingTurnedOff = !textCheckerState.isGrammarCheckingEnabled && m_textCheckerState.isGrammarCheckingEnabled;
1186 m_textCheckerState = textCheckerState;
1188 if (!continuousSpellCheckingTurnedOff && !grammarCheckingTurnedOff)
1191 HashMap<uint64_t, RefPtr<WebPage> >::iterator end = m_pageMap.end();
1192 for (HashMap<uint64_t, RefPtr<WebPage> >::iterator it = m_pageMap.begin(); it != end; ++it) {
1193 WebPage* page = (*it).second.get();
1194 if (continuousSpellCheckingTurnedOff)
1195 page->unmarkAllMisspellings();
1196 if (grammarCheckingTurnedOff)
1197 page->unmarkAllBadGrammar();
1201 void WebProcess::didGetPlugins(CoreIPC::Connection*, uint64_t requestID, const Vector<WebCore::PluginInfo>& plugins)
1203 #if USE(PLATFORM_STRATEGIES)
1204 // Pass this to WebPlatformStrategies.cpp.
1205 handleDidGetPlugins(requestID, plugins);
1209 } // namespace WebKit