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_RECORDING_SURFACE_PAINT_THREAD)
244 m_paintThreadWorkQueue = new WorkQueue("PaintThreadWorkQueue");
247 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
248 m_platformSurfacePool = adoptPtr(new PlatformSurfacePoolTizen());
251 #if ENABLE(TIZEN_JPEGIMAGE_DECODING_THREAD)
252 WebCore::AsyncImageDecoder::sharedAsyncImageDecoder();
255 startRandomCrashThreadIfRequested();
258 void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder* arguments)
260 ASSERT(m_pageMap.isEmpty());
262 platformInitializeWebProcess(parameters, arguments);
264 memoryPressureHandler().install();
266 RefPtr<APIObject> injectedBundleInitializationUserData;
267 InjectedBundleUserMessageDecoder messageDecoder(injectedBundleInitializationUserData);
268 if (!arguments->decode(messageDecoder))
271 if (!parameters.injectedBundlePath.isEmpty()) {
272 m_injectedBundle = InjectedBundle::create(parameters.injectedBundlePath);
273 m_injectedBundle->setSandboxExtension(SandboxExtension::create(parameters.injectedBundlePathExtensionHandle));
275 if (!m_injectedBundle->load(injectedBundleInitializationUserData.get())) {
276 // Don't keep around the InjectedBundle reference if the load fails.
277 m_injectedBundle.clear();
281 #if ENABLE(SQL_DATABASE)
282 // Make sure the WebDatabaseManager is initialized so that the Database directory is set.
283 WebDatabaseManager::initialize(parameters.databaseDirectory);
286 #if ENABLE(ICONDATABASE)
287 m_iconDatabaseProxy.setEnabled(parameters.iconDatabaseEnabled);
290 #if ENABLE(TIZEN_FILE_SYSTEM)
291 if (WebCore::makeAllDirectories(parameters.localFileSystemDirectory))
292 WebCore::LocalFileSystem::initializeLocalFileSystem(parameters.localFileSystemDirectory);
295 StorageTracker::initializeTracker(parameters.localStorageDirectory, &WebKeyValueStorageManager::shared());
296 m_localStorageDirectory = parameters.localStorageDirectory;
298 if (!parameters.applicationCacheDirectory.isEmpty())
299 cacheStorage().setCacheDirectory(parameters.applicationCacheDirectory);
301 #if ENABLE(TIZEN_WEBKIT2_VISITED_LINKS)
302 setShouldTrackVisitedLinks(true);
304 setShouldTrackVisitedLinks(parameters.shouldTrackVisitedLinks);
306 setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
308 if (!parameters.languages.isEmpty())
309 overrideUserPreferredLanguages(parameters.languages);
311 m_textCheckerState = parameters.textCheckerState;
313 m_fullKeyboardAccessEnabled = parameters.fullKeyboardAccessEnabled;
315 for (size_t i = 0; i < parameters.urlSchemesRegistererdAsEmptyDocument.size(); ++i)
316 registerURLSchemeAsEmptyDocument(parameters.urlSchemesRegistererdAsEmptyDocument[i]);
318 for (size_t i = 0; i < parameters.urlSchemesRegisteredAsSecure.size(); ++i)
319 registerURLSchemeAsSecure(parameters.urlSchemesRegisteredAsSecure[i]);
321 for (size_t i = 0; i < parameters.urlSchemesForWhichDomainRelaxationIsForbidden.size(); ++i)
322 setDomainRelaxationForbiddenForURLScheme(parameters.urlSchemesForWhichDomainRelaxationIsForbidden[i]);
324 setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval);
326 for (size_t i = 0; i < parameters.mimeTypesWithCustomRepresentation.size(); ++i)
327 m_mimeTypesWithCustomRepresentations.add(parameters.mimeTypesWithCustomRepresentation[i]);
330 m_presenterApplicationPid = parameters.presenterApplicationPid;
333 if (parameters.shouldAlwaysUseComplexTextCodePath)
334 setAlwaysUsesComplexTextCodePath(true);
336 if (parameters.shouldUseFontSmoothing)
337 setShouldUseFontSmoothing(true);
339 #if USE(CFURLSTORAGESESSIONS)
340 WebCore::ResourceHandle::setPrivateBrowsingStorageSessionIdentifierBase(parameters.uiProcessBundleIdentifier);
343 #if ENABLE(PLUGIN_PROCESS)
344 m_disablePluginProcessMessageTimeout = parameters.disablePluginProcessMessageTimeout;
347 #if ENABLE(TIZEN_INDEXED_DATABASE)
348 m_indexedDatabaseDirectory = parameters.indexedDatabaseDirectory;
351 #if ENABLE(TIZEN_EXTENSIBLE_API)
352 TizenExtensibleAPI::initializeTizenExtensibleAPI();
356 void WebProcess::setShouldTrackVisitedLinks(bool shouldTrackVisitedLinks)
358 m_shouldTrackVisitedLinks = shouldTrackVisitedLinks;
359 PageGroup::setShouldTrackVisitedLinks(shouldTrackVisitedLinks);
362 void WebProcess::registerURLSchemeAsEmptyDocument(const String& urlScheme)
364 SchemeRegistry::registerURLSchemeAsEmptyDocument(urlScheme);
367 void WebProcess::registerURLSchemeAsSecure(const String& urlScheme) const
369 SchemeRegistry::registerURLSchemeAsSecure(urlScheme);
372 void WebProcess::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) const
374 SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(true, urlScheme);
377 void WebProcess::setDefaultRequestTimeoutInterval(double timeoutInterval)
379 ResourceRequest::setDefaultTimeoutInterval(timeoutInterval);
382 void WebProcess::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
384 WebCore::Font::setCodePath(alwaysUseComplexText ? WebCore::Font::Complex : WebCore::Font::Auto);
387 void WebProcess::setShouldUseFontSmoothing(bool useFontSmoothing)
389 WebCore::Font::setShouldUseSmoothing(useFontSmoothing);
392 void WebProcess::userPreferredLanguagesChanged(const Vector<String>& languages) const
394 overrideUserPreferredLanguages(languages);
397 void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
399 m_fullKeyboardAccessEnabled = fullKeyboardAccessEnabled;
402 void WebProcess::setVisitedLinkTable(const SharedMemory::Handle& handle)
404 RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly);
408 m_visitedLinkTable.setSharedMemory(sharedMemory.release());
411 void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes)
413 // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext.
414 for (size_t i = 0; i < linkHashes.size(); ++i) {
415 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin();
416 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end();
417 for (; it != end; ++it)
418 Page::visitedStateChanged(PageGroup::pageGroup(it->second->identifier()), linkHashes[i]);
421 pageCache()->markPagesForVistedLinkStyleRecalc();
424 void WebProcess::allVisitedLinkStateChanged()
426 // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext.
427 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin();
428 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end();
429 for (; it != end; ++it)
430 Page::allVisitedStateChanged(PageGroup::pageGroup(it->second->identifier()));
432 pageCache()->markPagesForVistedLinkStyleRecalc();
435 bool WebProcess::isLinkVisited(LinkHash linkHash) const
437 return m_visitedLinkTable.isLinkVisited(linkHash);
440 void WebProcess::addVisitedLink(WebCore::LinkHash linkHash)
442 if (isLinkVisited(linkHash) || !m_shouldTrackVisitedLinks)
444 connection()->send(Messages::WebContext::AddVisitedLinkHash(linkHash), 0);
447 void WebProcess::setCacheModel(uint32_t cm)
449 CacheModel cacheModel = static_cast<CacheModel>(cm);
451 if (!m_hasSetCacheModel || cacheModel != m_cacheModel) {
452 m_hasSetCacheModel = true;
453 m_cacheModel = cacheModel;
454 platformSetCacheModel(cacheModel);
458 #if ENABLE(TIZEN_CACHE_CONTROL)
459 void WebProcess::setCacheDisabled(bool cacheDisabled)
461 platformSetCacheDisabled(cacheDisabled);
465 void WebProcess::calculateCacheSizes(CacheModel cacheModel, uint64_t memorySize, uint64_t diskFreeSize,
466 unsigned& cacheTotalCapacity, unsigned& cacheMinDeadCapacity, unsigned& cacheMaxDeadCapacity, double& deadDecodedDataDeletionInterval,
467 unsigned& pageCacheCapacity, unsigned long& urlCacheMemoryCapacity, unsigned long& urlCacheDiskCapacity)
469 switch (cacheModel) {
470 case CacheModelDocumentViewer: {
471 // Page cache capacity (in pages)
472 pageCacheCapacity = 0;
474 // Object cache capacities (in bytes)
475 if (memorySize >= 2048)
476 cacheTotalCapacity = 96 * 1024 * 1024;
477 else if (memorySize >= 1536)
478 cacheTotalCapacity = 64 * 1024 * 1024;
479 else if (memorySize >= 1024)
480 cacheTotalCapacity = 32 * 1024 * 1024;
481 else if (memorySize >= 512)
482 cacheTotalCapacity = 16 * 1024 * 1024;
484 cacheMinDeadCapacity = 0;
485 cacheMaxDeadCapacity = 0;
487 // Foundation memory cache capacity (in bytes)
488 urlCacheMemoryCapacity = 0;
490 // Foundation disk cache capacity (in bytes)
491 urlCacheDiskCapacity = 0;
495 case CacheModelDocumentBrowser: {
496 // Page cache capacity (in pages)
497 if (memorySize >= 1024)
498 pageCacheCapacity = 3;
499 else if (memorySize >= 512)
500 pageCacheCapacity = 2;
501 else if (memorySize >= 256)
502 pageCacheCapacity = 1;
504 pageCacheCapacity = 0;
506 // Object cache capacities (in bytes)
507 if (memorySize >= 2048)
508 cacheTotalCapacity = 96 * 1024 * 1024;
509 else if (memorySize >= 1536)
510 cacheTotalCapacity = 64 * 1024 * 1024;
511 else if (memorySize >= 1024)
512 cacheTotalCapacity = 32 * 1024 * 1024;
513 else if (memorySize >= 512)
514 cacheTotalCapacity = 16 * 1024 * 1024;
516 cacheMinDeadCapacity = cacheTotalCapacity / 8;
517 cacheMaxDeadCapacity = cacheTotalCapacity / 4;
519 // Foundation memory cache capacity (in bytes)
520 if (memorySize >= 2048)
521 urlCacheMemoryCapacity = 4 * 1024 * 1024;
522 else if (memorySize >= 1024)
523 urlCacheMemoryCapacity = 2 * 1024 * 1024;
524 else if (memorySize >= 512)
525 urlCacheMemoryCapacity = 1 * 1024 * 1024;
527 urlCacheMemoryCapacity = 512 * 1024;
529 // Foundation disk cache capacity (in bytes)
530 if (diskFreeSize >= 16384)
531 urlCacheDiskCapacity = 50 * 1024 * 1024;
532 else if (diskFreeSize >= 8192)
533 urlCacheDiskCapacity = 40 * 1024 * 1024;
534 else if (diskFreeSize >= 4096)
535 urlCacheDiskCapacity = 30 * 1024 * 1024;
537 urlCacheDiskCapacity = 20 * 1024 * 1024;
541 case CacheModelPrimaryWebBrowser: {
542 // Page cache capacity (in pages)
543 // (Research indicates that value / page drops substantially after 3 pages.)
544 if (memorySize >= 2048)
545 pageCacheCapacity = 5;
546 else if (memorySize >= 1024)
547 pageCacheCapacity = 4;
548 else if (memorySize >= 512)
549 pageCacheCapacity = 3;
550 else if (memorySize >= 256)
551 pageCacheCapacity = 2;
553 pageCacheCapacity = 1;
555 // Object cache capacities (in bytes)
556 // (Testing indicates that value / MB depends heavily on content and
557 // browsing pattern. Even growth above 128MB can have substantial
558 // value / MB for some content / browsing patterns.)
559 if (memorySize >= 2048)
560 cacheTotalCapacity = 128 * 1024 * 1024;
561 else if (memorySize >= 1536)
562 cacheTotalCapacity = 96 * 1024 * 1024;
563 else if (memorySize >= 1024)
564 cacheTotalCapacity = 64 * 1024 * 1024;
565 else if (memorySize >= 512)
566 cacheTotalCapacity = 32 * 1024 * 1024;
568 cacheMinDeadCapacity = cacheTotalCapacity / 4;
569 cacheMaxDeadCapacity = cacheTotalCapacity / 2;
571 // This code is here to avoid a PLT regression. We can remove it if we
572 // can prove that the overall system gain would justify the regression.
573 cacheMaxDeadCapacity = std::max(24u, cacheMaxDeadCapacity);
575 deadDecodedDataDeletionInterval = 60;
577 // Foundation memory cache capacity (in bytes)
578 // (These values are small because WebCore does most caching itself.)
579 if (memorySize >= 1024)
580 urlCacheMemoryCapacity = 4 * 1024 * 1024;
581 else if (memorySize >= 512)
582 urlCacheMemoryCapacity = 2 * 1024 * 1024;
583 else if (memorySize >= 256)
584 urlCacheMemoryCapacity = 1 * 1024 * 1024;
586 urlCacheMemoryCapacity = 512 * 1024;
588 // Foundation disk cache capacity (in bytes)
589 if (diskFreeSize >= 16384)
590 urlCacheDiskCapacity = 175 * 1024 * 1024;
591 else if (diskFreeSize >= 8192)
592 urlCacheDiskCapacity = 150 * 1024 * 1024;
593 else if (diskFreeSize >= 4096)
594 urlCacheDiskCapacity = 125 * 1024 * 1024;
595 else if (diskFreeSize >= 2048)
596 urlCacheDiskCapacity = 100 * 1024 * 1024;
597 else if (diskFreeSize >= 1024)
598 urlCacheDiskCapacity = 75 * 1024 * 1024;
600 urlCacheDiskCapacity = 50 * 1024 * 1024;
605 ASSERT_NOT_REACHED();
609 WebPage* WebProcess::focusedWebPage() const
611 HashMap<uint64_t, RefPtr<WebPage> >::const_iterator end = m_pageMap.end();
612 for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator it = m_pageMap.begin(); it != end; ++it) {
613 WebPage* page = (*it).second.get();
614 if (page->windowAndWebPageAreFocused())
620 WebPage* WebProcess::webPage(uint64_t pageID) const
622 return m_pageMap.get(pageID).get();
625 void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
627 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
628 if (!m_platformSurfacePool)
629 m_platformSurfacePool = adoptPtr(new PlatformSurfacePoolTizen());
631 // It is necessary to check for page existence here since during a window.open() (or targeted
632 // link) the WebPage gets created both in the synchronous handler and through the normal way.
633 HashMap<uint64_t, RefPtr<WebPage> >::AddResult result = m_pageMap.add(pageID, 0);
634 if (result.isNewEntry) {
635 ASSERT(!result.iterator->second);
636 result.iterator->second = WebPage::create(pageID, parameters);
638 // Balanced by an enableTermination in removeWebPage.
639 disableTermination();
642 ASSERT(result.iterator->second);
645 void WebProcess::removeWebPage(uint64_t pageID)
647 ASSERT(m_pageMap.contains(pageID));
649 m_pageMap.remove(pageID);
651 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
652 if (m_pageMap.size() == 0)
653 m_platformSurfacePool = nullptr;
659 bool WebProcess::isSeparateProcess() const
661 // If we're running on the main run loop, we assume that we're in a separate process.
662 return m_runLoop == RunLoop::main();
665 bool WebProcess::shouldTerminate()
667 // Keep running forever if we're running in the same process.
668 if (!isSeparateProcess())
671 ASSERT(m_pageMap.isEmpty());
672 ASSERT(!DownloadManager::shared().isDownloading());
674 // FIXME: the ShouldTerminate message should also send termination parameters, such as any session cookies that need to be preserved.
675 bool shouldTerminate = false;
676 if (connection()->sendSync(Messages::WebProcessProxy::ShouldTerminate(), Messages::WebProcessProxy::ShouldTerminate::Reply(shouldTerminate), 0)
683 void WebProcess::terminate()
686 gcController().garbageCollectNow();
687 memoryCache()->setDisabled(true);
690 // Invalidate our connection.
691 m_connection->invalidate();
692 m_connection = nullptr;
698 void WebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply)
700 #if ENABLE(TIZEN_NOTIFICATIONS)
701 if (messageID.is<CoreIPC::MessageClassWebNotificationManager>()) {
702 m_notificationManager.didReceiveSyncMessage(connection, messageID, arguments, reply);
707 #if ENABLE(TIZEN_CACHE_DUMP_SYNC)
708 if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) {
709 WebResourceCacheManager::shared().didReceiveSyncMessage(connection, messageID, arguments, reply);
714 uint64_t pageID = arguments->destinationID();
718 WebPage* page = webPage(pageID);
722 page->didReceiveSyncMessage(connection, messageID, arguments, reply);
725 void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
727 if (messageID.is<CoreIPC::MessageClassWebProcess>()) {
728 didReceiveWebProcessMessage(connection, messageID, arguments);
732 if (messageID.is<CoreIPC::MessageClassAuthenticationManager>()) {
733 AuthenticationManager::shared().didReceiveMessage(connection, messageID, arguments);
737 if (messageID.is<CoreIPC::MessageClassWebApplicationCacheManager>()) {
738 WebApplicationCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
742 if (messageID.is<CoreIPC::MessageClassWebCookieManager>()) {
743 WebCookieManager::shared().didReceiveMessage(connection, messageID, arguments);
747 #if ENABLE(SQL_DATABASE)
748 if (messageID.is<CoreIPC::MessageClassWebDatabaseManager>()) {
749 WebDatabaseManager::shared().didReceiveMessage(connection, messageID, arguments);
754 if (messageID.is<CoreIPC::MessageClassWebGeolocationManager>()) {
755 m_geolocationManager.didReceiveMessage(connection, messageID, arguments);
759 #if ENABLE(BATTERY_STATUS)
760 if (messageID.is<CoreIPC::MessageClassWebBatteryManager>()) {
761 m_batteryManager.didReceiveMessage(connection, messageID, arguments);
766 #if ENABLE(NETWORK_INFO)
767 if (messageID.is<CoreIPC::MessageClassWebNetworkInfoManager>()) {
768 m_networkInfoManager.didReceiveMessage(connection, messageID, arguments);
773 if (messageID.is<CoreIPC::MessageClassWebIconDatabaseProxy>()) {
774 m_iconDatabaseProxy.didReceiveMessage(connection, messageID, arguments);
778 if (messageID.is<CoreIPC::MessageClassWebKeyValueStorageManager>()) {
779 WebKeyValueStorageManager::shared().didReceiveMessage(connection, messageID, arguments);
783 #if ENABLE(TIZEN_FILE_SYSTEM)
784 if (messageID.is<CoreIPC::MessageClassWebLocalFileSystemManager>()) {
785 WebLocalFileSystemManager::shared().didReceiveMessage(connection, messageID, arguments);
790 if (messageID.is<CoreIPC::MessageClassWebMediaCacheManager>()) {
791 WebMediaCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
795 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
796 if (messageID.is<CoreIPC::MessageClassWebNotificationManager>()) {
797 m_notificationManager.didReceiveMessage(connection, messageID, arguments);
802 if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) {
803 WebResourceCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
808 if (messageID.is<CoreIPC::MessageClassWebSoupRequestManager>()) {
809 m_soupRequestManager.didReceiveMessage(connection, messageID, arguments);
814 if (messageID.is<CoreIPC::MessageClassInjectedBundle>()) {
815 if (!m_injectedBundle)
817 m_injectedBundle->didReceiveMessage(connection, messageID, arguments);
821 uint64_t pageID = arguments->destinationID();
825 WebPage* page = webPage(pageID);
829 page->didReceiveMessage(connection, messageID, arguments);
832 void WebProcess::didClose(CoreIPC::Connection*)
834 // When running in the same process the connection will never be closed.
835 ASSERT(isSeparateProcess());
840 // Close all the live pages.
841 Vector<RefPtr<WebPage> > pages;
842 copyValuesToVector(m_pageMap, pages);
843 for (size_t i = 0; i < pages.size(); ++i)
847 gcController().garbageCollectSoon();
848 memoryCache()->setDisabled(true);
851 // The UI process closed this connection, shut down.
855 void WebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID)
857 // We received an invalid message, but since this is from the UI process (which we trust),
858 // we'll let it slide.
861 void WebProcess::syncMessageSendTimedOut(CoreIPC::Connection*)
865 void WebProcess::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage)
867 if (messageID.is<CoreIPC::MessageClassWebProcess>()) {
868 didReceiveWebProcessMessageOnConnectionWorkQueue(connection, messageID, arguments, didHandleMessage);
873 WebFrame* WebProcess::webFrame(uint64_t frameID) const
875 return m_frameMap.get(frameID);
878 void WebProcess::addWebFrame(uint64_t frameID, WebFrame* frame)
880 m_frameMap.set(frameID, frame);
883 void WebProcess::removeWebFrame(uint64_t frameID)
885 m_frameMap.remove(frameID);
887 // We can end up here after our connection has closed when WebCore's frame life-support timer
888 // fires when the application is shutting down. There's no need (and no way) to update the UI
889 // process in this case.
893 connection()->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0);
896 WebPageGroupProxy* WebProcess::webPageGroup(uint64_t pageGroupID)
898 return m_pageGroupMap.get(pageGroupID).get();
901 WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupData)
903 HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::AddResult result = m_pageGroupMap.add(pageGroupData.pageGroupID, 0);
904 if (result.isNewEntry) {
905 ASSERT(!result.iterator->second);
906 result.iterator->second = WebPageGroupProxy::create(pageGroupData);
909 return result.iterator->second.get();
912 static bool canPluginHandleResponse(const ResourceResponse& response)
917 if (!WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPluginPath(response.mimeType(), response.url().string()), Messages::WebContext::GetPluginPath::Reply(pluginPath, blocked), 0))
920 return !blocked && !pluginPath.isEmpty();
923 bool WebProcess::shouldUseCustomRepresentationForResponse(const ResourceResponse& response) const
925 if (!m_mimeTypesWithCustomRepresentations.contains(response.mimeType()))
928 // If a plug-in exists that claims to support this response, it should take precedence over the custom representation.
929 return !canPluginHandleResponse(response);
932 void WebProcess::clearResourceCaches(ResourceCachesToClear resourceCachesToClear)
934 #if ENABLE(TIZEN_CACHE_MEMORY_OPTIMIZATION)
935 if(resourceCachesToClear == InDecodedDataResourceCachesOnly) {
936 memoryCache()->removeAllDecodedData();
941 platformClearResourceCaches(resourceCachesToClear);
943 // Toggling the cache model like this forces the cache to evict all its in-memory resources.
944 // FIXME: We need a better way to do this.
945 CacheModel cacheModel = m_cacheModel;
946 setCacheModel(CacheModelDocumentViewer);
947 setCacheModel(cacheModel);
949 memoryCache()->evictResources();
951 // Empty the cross-origin preflight cache.
952 CrossOriginPreflightResultCache::shared().empty();
955 #if ENABLE(TIZEN_CACHE_DUMP_SYNC)
956 void WebProcess::dumpResourceCaches()
958 platformDumpResourceCaches();
962 void WebProcess::clearApplicationCache()
964 // Empty the application cache.
965 cacheStorage().empty();
968 #if !ENABLE(PLUGIN_PROCESS)
969 void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint64_t callbackID)
971 LocalTerminationDisabler terminationDisabler(*this);
973 HashSet<String> sitesSet;
975 #if ENABLE(NETSCAPE_PLUGIN_API)
976 for (size_t i = 0; i < pluginPaths.size(); ++i) {
977 RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]);
978 if (!netscapePluginModule)
981 Vector<String> sites = netscapePluginModule->sitesWithData();
982 for (size_t i = 0; i < sites.size(); ++i)
983 sitesSet.add(sites[i]);
987 Vector<String> sites;
988 copyToVector(sitesSet, sites);
990 connection()->send(Messages::WebContext::DidGetSitesWithPluginData(sites, callbackID), 0);
993 void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID)
995 LocalTerminationDisabler terminationDisabler(*this);
997 #if ENABLE(NETSCAPE_PLUGIN_API)
998 for (size_t i = 0; i < pluginPaths.size(); ++i) {
999 RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]);
1000 if (!netscapePluginModule)
1003 if (sites.isEmpty()) {
1004 // Clear everything.
1005 netscapePluginModule->clearSiteData(String(), flags, maxAgeInSeconds);
1009 for (size_t i = 0; i < sites.size(); ++i)
1010 netscapePluginModule->clearSiteData(sites[i], flags, maxAgeInSeconds);
1014 connection()->send(Messages::WebContext::DidClearPluginSiteData(callbackID), 0);
1018 static void fromCountedSetToHashMap(TypeCountSet* countedSet, HashMap<String, uint64_t>& map)
1020 TypeCountSet::const_iterator end = countedSet->end();
1021 for (TypeCountSet::const_iterator it = countedSet->begin(); it != end; ++it)
1022 map.set(it->first, it->second);
1025 static void getWebCoreMemoryCacheStatistics(Vector<HashMap<String, uint64_t> >& result)
1027 DEFINE_STATIC_LOCAL(String, imagesString, ("Images"));
1028 DEFINE_STATIC_LOCAL(String, cssString, ("CSS"));
1029 DEFINE_STATIC_LOCAL(String, xslString, ("XSL"));
1030 DEFINE_STATIC_LOCAL(String, javaScriptString, ("JavaScript"));
1032 MemoryCache::Statistics memoryCacheStatistics = memoryCache()->getStatistics();
1034 HashMap<String, uint64_t> counts;
1035 counts.set(imagesString, memoryCacheStatistics.images.count);
1036 counts.set(cssString, memoryCacheStatistics.cssStyleSheets.count);
1037 counts.set(xslString, memoryCacheStatistics.xslStyleSheets.count);
1038 counts.set(javaScriptString, memoryCacheStatistics.scripts.count);
1039 result.append(counts);
1041 HashMap<String, uint64_t> sizes;
1042 sizes.set(imagesString, memoryCacheStatistics.images.size);
1043 sizes.set(cssString, memoryCacheStatistics.cssStyleSheets.size);
1044 sizes.set(xslString, memoryCacheStatistics.xslStyleSheets.size);
1045 sizes.set(javaScriptString, memoryCacheStatistics.scripts.size);
1046 result.append(sizes);
1048 HashMap<String, uint64_t> liveSizes;
1049 liveSizes.set(imagesString, memoryCacheStatistics.images.liveSize);
1050 liveSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.liveSize);
1051 liveSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.liveSize);
1052 liveSizes.set(javaScriptString, memoryCacheStatistics.scripts.liveSize);
1053 result.append(liveSizes);
1055 HashMap<String, uint64_t> decodedSizes;
1056 decodedSizes.set(imagesString, memoryCacheStatistics.images.decodedSize);
1057 decodedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.decodedSize);
1058 decodedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.decodedSize);
1059 decodedSizes.set(javaScriptString, memoryCacheStatistics.scripts.decodedSize);
1060 result.append(decodedSizes);
1062 HashMap<String, uint64_t> purgeableSizes;
1063 purgeableSizes.set(imagesString, memoryCacheStatistics.images.purgeableSize);
1064 purgeableSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgeableSize);
1065 purgeableSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgeableSize);
1066 purgeableSizes.set(javaScriptString, memoryCacheStatistics.scripts.purgeableSize);
1067 result.append(purgeableSizes);
1069 HashMap<String, uint64_t> purgedSizes;
1070 purgedSizes.set(imagesString, memoryCacheStatistics.images.purgedSize);
1071 purgedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgedSize);
1072 purgedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgedSize);
1073 purgedSizes.set(javaScriptString, memoryCacheStatistics.scripts.purgedSize);
1074 result.append(purgedSizes);
1077 void WebProcess::getWebCoreStatistics(uint64_t callbackID)
1079 StatisticsData data;
1081 // Gather JavaScript statistics.
1083 JSLockHolder lock(JSDOMWindow::commonJSGlobalData());
1084 data.statisticsNumbers.set("JavaScriptObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.objectCount());
1085 data.statisticsNumbers.set("JavaScriptGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount());
1086 data.statisticsNumbers.set("JavaScriptProtectedObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount());
1087 data.statisticsNumbers.set("JavaScriptProtectedGlobalObjectsCount", JSDOMWindow::commonJSGlobalData()->heap.protectedGlobalObjectCount());
1089 OwnPtr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts());
1090 fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts);
1092 OwnPtr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.objectTypeCounts());
1093 fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts);
1095 uint64_t javaScriptHeapSize = JSDOMWindow::commonJSGlobalData()->heap.size();
1096 data.statisticsNumbers.set("JavaScriptHeapSize", javaScriptHeapSize);
1097 data.statisticsNumbers.set("JavaScriptFreeSize", JSDOMWindow::commonJSGlobalData()->heap.capacity() - javaScriptHeapSize);
1100 WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics();
1101 data.statisticsNumbers.set("FastMallocReservedVMBytes", fastMallocStatistics.reservedVMBytes);
1102 data.statisticsNumbers.set("FastMallocCommittedVMBytes", fastMallocStatistics.committedVMBytes);
1103 data.statisticsNumbers.set("FastMallocFreeListBytes", fastMallocStatistics.freeListBytes);
1105 // Gather icon statistics.
1106 data.statisticsNumbers.set("IconPageURLMappingCount", iconDatabase().pageURLMappingCount());
1107 data.statisticsNumbers.set("IconRetainedPageURLCount", iconDatabase().retainedPageURLCount());
1108 data.statisticsNumbers.set("IconRecordCount", iconDatabase().iconRecordCount());
1109 data.statisticsNumbers.set("IconsWithDataCount", iconDatabase().iconRecordCountWithData());
1111 // Gather font statistics.
1112 data.statisticsNumbers.set("CachedFontDataCount", fontCache()->fontDataCount());
1113 data.statisticsNumbers.set("CachedFontDataInactiveCount", fontCache()->inactiveFontDataCount());
1115 // Gather glyph page statistics.
1116 #if !(PLATFORM(QT) && !HAVE(QRAWFONT)) // Qt doesn't use the glyph page tree currently. See: bug 63467.
1117 data.statisticsNumbers.set("GlyphPageCount", GlyphPageTreeNode::treeGlyphPageCount());
1120 // Get WebCore memory cache statistics
1121 getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics);
1123 connection()->send(Messages::WebContext::DidGetWebCoreStatistics(data, callbackID), 0);
1126 void WebProcess::garbageCollectJavaScriptObjects()
1128 gcController().garbageCollectNow();
1131 void WebProcess::setJavaScriptGarbageCollectorTimerEnabled(bool flag)
1133 gcController().setJavaScriptGarbageCollectorTimerEnabled(flag);
1136 #if ENABLE(PLUGIN_PROCESS)
1137 void WebProcess::pluginProcessCrashed(CoreIPC::Connection*, const String& pluginPath)
1139 m_pluginProcessConnectionManager.pluginProcessCrashed(pluginPath);
1143 void WebProcess::downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, const ResourceRequest& request)
1145 WebPage* initiatingPage = initiatingPageID ? webPage(initiatingPageID) : 0;
1147 ResourceRequest requestWithOriginalURL = request;
1149 initiatingPage->mainFrame()->loader()->setOriginalURLForDownloadRequest(requestWithOriginalURL);
1151 DownloadManager::shared().startDownload(downloadID, initiatingPage, requestWithOriginalURL);
1154 void WebProcess::cancelDownload(uint64_t downloadID)
1156 DownloadManager::shared().cancelDownload(downloadID);
1160 void WebProcess::startTransfer(uint64_t downloadID, const String& destination)
1162 DownloadManager::shared().startTransfer(downloadID, destination);
1166 void WebProcess::setEnhancedAccessibility(bool flag)
1168 WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility(flag);
1171 void WebProcess::startMemorySampler(const SandboxExtension::Handle& sampleLogFileHandle, const String& sampleLogFilePath, const double interval)
1173 #if ENABLE(MEMORY_SAMPLER)
1174 WebMemorySampler::shared()->start(sampleLogFileHandle, sampleLogFilePath, interval);
1178 void WebProcess::stopMemorySampler()
1180 #if ENABLE(MEMORY_SAMPLER)
1181 WebMemorySampler::shared()->stop();
1185 void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState)
1187 bool continuousSpellCheckingTurnedOff = !textCheckerState.isContinuousSpellCheckingEnabled && m_textCheckerState.isContinuousSpellCheckingEnabled;
1188 bool grammarCheckingTurnedOff = !textCheckerState.isGrammarCheckingEnabled && m_textCheckerState.isGrammarCheckingEnabled;
1190 m_textCheckerState = textCheckerState;
1192 if (!continuousSpellCheckingTurnedOff && !grammarCheckingTurnedOff)
1195 HashMap<uint64_t, RefPtr<WebPage> >::iterator end = m_pageMap.end();
1196 for (HashMap<uint64_t, RefPtr<WebPage> >::iterator it = m_pageMap.begin(); it != end; ++it) {
1197 WebPage* page = (*it).second.get();
1198 if (continuousSpellCheckingTurnedOff)
1199 page->unmarkAllMisspellings();
1200 if (grammarCheckingTurnedOff)
1201 page->unmarkAllBadGrammar();
1205 void WebProcess::didGetPlugins(CoreIPC::Connection*, uint64_t requestID, const Vector<WebCore::PluginInfo>& plugins)
1207 #if USE(PLATFORM_STRATEGIES)
1208 // Pass this to WebPlatformStrategies.cpp.
1209 handleDidGetPlugins(requestID, plugins);
1213 } // namespace WebKit