Cancel composition when focused node was changed
[framework/web/webkit-efl.git] / Source / WebKit2 / WebProcess / WebProcess.cpp
1 /*
2  * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebProcess.h"
28
29 #include "AuthenticationManager.h"
30 #include "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"
41 #include "WebFrame.h"
42 #include "WebGeolocationManagerMessages.h"
43 #include "WebKeyValueStorageManager.h"
44 #include "WebMediaCacheManager.h"
45 #include "WebMemorySampler.h"
46 #include "WebPage.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>
82
83 #if ENABLE(NETWORK_INFO)
84 #include "WebNetworkInfoManagerMessages.h"
85 #endif
86
87 #if !OS(WINDOWS)
88 #include <unistd.h>
89 #endif
90
91 #if !ENABLE(PLUGIN_PROCESS)
92 #include "NetscapePluginModule.h"
93 #endif
94
95 #if ENABLE(TIZEN_FILE_SYSTEM)
96 #include "FileSystem.h"
97 #include "WebLocalFileSystemManager.h"
98 #include <WebCore/LocalFileSystem.h>
99 #endif
100
101 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
102 #include "WebPage/efl/tizen/PlatformSurfacePoolTizen.h"
103 #endif
104
105 #if ENABLE(TIZEN_LOG)
106 #include "Logging.h"
107 #endif
108
109 #if ENABLE(TIZEN_EXTENSIBLE_API)
110 #include <WebCore/TizenExtensibleAPI.h>
111 #endif
112
113 using namespace JSC;
114 using namespace WebCore;
115
116 namespace WebKit {
117
118 #if OS(WINDOWS)
119 static void sleep(unsigned seconds)
120 {
121     ::Sleep(seconds * 1000);
122 }
123 #endif
124
125 static void randomCrashThread(void*) NO_RETURN_DUE_TO_CRASH;
126 void randomCrashThread(void*)
127 {
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
130     // after launch.
131     static const unsigned maximumRandomCrashDelay = 180;
132
133     sleep(randomNumber() * maximumRandomCrashDelay);
134     CRASH();
135 }
136
137 static void startRandomCrashThreadIfRequested()
138 {
139     if (!getenv("WEBKIT2_CRASH_WEB_PROCESS_RANDOMLY"))
140         return;
141     createThread(randomCrashThread, 0, "WebKit2: Random Crash Thread");
142 }
143
144 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
145 WebProcess::WaitForJavaScriptPopupFinished::WaitForJavaScriptPopupFinished()
146 {
147     ++WebProcess::shared().m_isWaitingForJavaScriptPopupCount;
148 }
149
150 WebProcess::WaitForJavaScriptPopupFinished::~WaitForJavaScriptPopupFinished()
151 {
152     --WebProcess::shared().m_isWaitingForJavaScriptPopupCount;
153 }
154
155 bool WebProcess::isWaitingForJavaScriptPopupFinished()
156 {
157     return m_isWaitingForJavaScriptPopupCount > 0;
158 }
159 #endif
160
161 WebProcess& WebProcess::shared()
162 {
163     static WebProcess& process = *new WebProcess;
164     return process;
165 }
166
167 static const double shutdownTimeout = 60;
168
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)
177 #endif
178 #if PLATFORM(MAC)
179     , m_clearResourceCachesDispatchGroup(0)
180 #endif
181     , m_fullKeyboardAccessEnabled(false)
182 #if PLATFORM(QT)
183     , m_networkAccessManager(0)
184 #endif
185     , m_textCheckerState()
186     , m_geolocationManager(this)
187 #if ENABLE(BATTERY_STATUS)
188     , m_batteryManager(this)
189 #endif
190 #if ENABLE(NETWORK_INFO)
191     , m_networkInfoManager(this)
192 #endif
193 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
194     , m_notificationManager(this)
195 #endif
196     , m_iconDatabaseProxy(this)
197 #if ENABLE(PLUGIN_PROCESS)
198     , m_disablePluginProcessMessageTimeout(false)
199 #endif
200 #if USE(SOUP)
201     , m_soupRequestManager(this)
202 #endif
203 #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP)
204     , m_isWaitingForJavaScriptPopupCount(0)
205 #endif
206 #if ENABLE(TIZEN_WEBKIT2_MEMORY_SAVING_MODE)
207     , m_memorySavingModeEnabled(false)
208 #endif
209 {
210 #if USE(PLATFORM_STRATEGIES)
211     // Initialize our platform strategies.
212     WebPlatformStrategies::initialize();
213 #endif // USE(PLATFORM_STRATEGIES)
214
215 #if !LOG_DISABLED && ENABLE(TIZEN_LOG)
216     WebKit::initializeLogChannelsIfNecessary();
217 #endif
218
219 #if !LOG_DISABLED
220     WebCore::initializeLoggingChannelsIfNecessary();
221 #endif // !LOG_DISABLED
222 }
223
224 void WebProcess::initialize(CoreIPC::Connection::Identifier serverIdentifier, RunLoop* runLoop)
225 {
226     ASSERT(!m_connection);
227
228     m_connection = WebConnectionToUIProcess::create(this, serverIdentifier, runLoop);
229
230     m_connection->connection()->addQueueClient(&m_eventDispatcher);
231     m_connection->connection()->addQueueClient(this);
232
233     m_connection->connection()->open();
234     m_runLoop = runLoop;
235
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);
241 #endif
242
243 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
244     m_platformSurfacePool = adoptPtr(new PlatformSurfacePoolTizen());
245 #endif
246
247 #if ENABLE(TIZEN_JPEGIMAGE_DECODING_THREAD)
248     WebCore::AsyncImageDecoder::sharedAsyncImageDecoder();
249 #endif
250
251     startRandomCrashThreadIfRequested();
252 }
253
254 void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder* arguments)
255 {
256     ASSERT(m_pageMap.isEmpty());
257
258     platformInitializeWebProcess(parameters, arguments);
259
260     memoryPressureHandler().install();
261
262     RefPtr<APIObject> injectedBundleInitializationUserData;
263     InjectedBundleUserMessageDecoder messageDecoder(injectedBundleInitializationUserData);
264     if (!arguments->decode(messageDecoder))
265         return;
266
267     if (!parameters.injectedBundlePath.isEmpty()) {
268         m_injectedBundle = InjectedBundle::create(parameters.injectedBundlePath);
269         m_injectedBundle->setSandboxExtension(SandboxExtension::create(parameters.injectedBundlePathExtensionHandle));
270
271         if (!m_injectedBundle->load(injectedBundleInitializationUserData.get())) {
272             // Don't keep around the InjectedBundle reference if the load fails.
273             m_injectedBundle.clear();
274         }
275     }
276
277 #if ENABLE(SQL_DATABASE)
278     // Make sure the WebDatabaseManager is initialized so that the Database directory is set.
279     WebDatabaseManager::initialize(parameters.databaseDirectory);
280 #endif
281
282 #if ENABLE(ICONDATABASE)
283     m_iconDatabaseProxy.setEnabled(parameters.iconDatabaseEnabled);
284 #endif
285
286 #if ENABLE(TIZEN_FILE_SYSTEM)
287     if (WebCore::makeAllDirectories(parameters.localFileSystemDirectory))
288         WebCore::LocalFileSystem::initializeLocalFileSystem(parameters.localFileSystemDirectory);
289 #endif
290
291     StorageTracker::initializeTracker(parameters.localStorageDirectory, &WebKeyValueStorageManager::shared());
292     m_localStorageDirectory = parameters.localStorageDirectory;
293
294     if (!parameters.applicationCacheDirectory.isEmpty())
295         cacheStorage().setCacheDirectory(parameters.applicationCacheDirectory);
296
297 #if ENABLE(TIZEN_WEBKIT2_VISITED_LINKS)
298     setShouldTrackVisitedLinks(true);
299 #else
300     setShouldTrackVisitedLinks(parameters.shouldTrackVisitedLinks);
301 #endif
302     setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
303
304     if (!parameters.languages.isEmpty())
305         overrideUserPreferredLanguages(parameters.languages);
306
307     m_textCheckerState = parameters.textCheckerState;
308
309     m_fullKeyboardAccessEnabled = parameters.fullKeyboardAccessEnabled;
310
311     for (size_t i = 0; i < parameters.urlSchemesRegistererdAsEmptyDocument.size(); ++i)
312         registerURLSchemeAsEmptyDocument(parameters.urlSchemesRegistererdAsEmptyDocument[i]);
313
314     for (size_t i = 0; i < parameters.urlSchemesRegisteredAsSecure.size(); ++i)
315         registerURLSchemeAsSecure(parameters.urlSchemesRegisteredAsSecure[i]);
316
317     for (size_t i = 0; i < parameters.urlSchemesForWhichDomainRelaxationIsForbidden.size(); ++i)
318         setDomainRelaxationForbiddenForURLScheme(parameters.urlSchemesForWhichDomainRelaxationIsForbidden[i]);
319
320     setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval);
321
322     for (size_t i = 0; i < parameters.mimeTypesWithCustomRepresentation.size(); ++i)
323         m_mimeTypesWithCustomRepresentations.add(parameters.mimeTypesWithCustomRepresentation[i]);
324     
325 #if PLATFORM(MAC)
326     m_presenterApplicationPid = parameters.presenterApplicationPid;
327 #endif
328
329     if (parameters.shouldAlwaysUseComplexTextCodePath)
330         setAlwaysUsesComplexTextCodePath(true);
331
332     if (parameters.shouldUseFontSmoothing)
333         setShouldUseFontSmoothing(true);
334
335 #if USE(CFURLSTORAGESESSIONS)
336     WebCore::ResourceHandle::setPrivateBrowsingStorageSessionIdentifierBase(parameters.uiProcessBundleIdentifier);
337 #endif
338
339 #if ENABLE(PLUGIN_PROCESS)
340     m_disablePluginProcessMessageTimeout = parameters.disablePluginProcessMessageTimeout;
341 #endif
342
343 #if ENABLE(TIZEN_INDEXED_DATABASE)
344     m_indexedDatabaseDirectory = parameters.indexedDatabaseDirectory;
345 #endif
346
347 #if ENABLE(TIZEN_EXTENSIBLE_API)
348     TizenExtensibleAPI::initializeTizenExtensibleAPI();
349 #endif
350 }
351
352 void WebProcess::setShouldTrackVisitedLinks(bool shouldTrackVisitedLinks)
353 {
354     m_shouldTrackVisitedLinks = shouldTrackVisitedLinks;
355     PageGroup::setShouldTrackVisitedLinks(shouldTrackVisitedLinks);
356 }
357
358 void WebProcess::registerURLSchemeAsEmptyDocument(const String& urlScheme)
359 {
360     SchemeRegistry::registerURLSchemeAsEmptyDocument(urlScheme);
361 }
362
363 void WebProcess::registerURLSchemeAsSecure(const String& urlScheme) const
364 {
365     SchemeRegistry::registerURLSchemeAsSecure(urlScheme);
366 }
367
368 void WebProcess::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) const
369 {
370     SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(true, urlScheme);
371 }
372
373 void WebProcess::setDefaultRequestTimeoutInterval(double timeoutInterval)
374 {
375     ResourceRequest::setDefaultTimeoutInterval(timeoutInterval);
376 }
377
378 void WebProcess::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
379 {
380     WebCore::Font::setCodePath(alwaysUseComplexText ? WebCore::Font::Complex : WebCore::Font::Auto);
381 }
382
383 void WebProcess::setShouldUseFontSmoothing(bool useFontSmoothing)
384 {
385     WebCore::Font::setShouldUseSmoothing(useFontSmoothing);
386 }
387
388 void WebProcess::userPreferredLanguagesChanged(const Vector<String>& languages) const
389 {
390     overrideUserPreferredLanguages(languages);
391 }
392
393 void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
394 {
395     m_fullKeyboardAccessEnabled = fullKeyboardAccessEnabled;
396 }
397
398 void WebProcess::setVisitedLinkTable(const SharedMemory::Handle& handle)
399 {
400     RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly);
401     if (!sharedMemory)
402         return;
403
404     m_visitedLinkTable.setSharedMemory(sharedMemory.release());
405 }
406
407 void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes)
408 {
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]);
415     }
416
417     pageCache()->markPagesForVistedLinkStyleRecalc();
418 }
419
420 void WebProcess::allVisitedLinkStateChanged()
421 {
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()));
427
428     pageCache()->markPagesForVistedLinkStyleRecalc();
429 }
430
431 bool WebProcess::isLinkVisited(LinkHash linkHash) const
432 {
433     return m_visitedLinkTable.isLinkVisited(linkHash);
434 }
435
436 void WebProcess::addVisitedLink(WebCore::LinkHash linkHash)
437 {
438     if (isLinkVisited(linkHash) || !m_shouldTrackVisitedLinks)
439         return;
440     connection()->send(Messages::WebContext::AddVisitedLinkHash(linkHash), 0);
441 }
442
443 void WebProcess::setCacheModel(uint32_t cm)
444 {
445     CacheModel cacheModel = static_cast<CacheModel>(cm);
446
447     if (!m_hasSetCacheModel || cacheModel != m_cacheModel) {
448         m_hasSetCacheModel = true;
449         m_cacheModel = cacheModel;
450         platformSetCacheModel(cacheModel);
451     }
452 }
453
454 #if ENABLE(TIZEN_CACHE_CONTROL)
455 void WebProcess::setCacheDisabled(bool cacheDisabled)
456 {
457     platformSetCacheDisabled(cacheDisabled);
458 }
459 #endif
460
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)
464 {
465     switch (cacheModel) {
466     case CacheModelDocumentViewer: {
467         // Page cache capacity (in pages)
468         pageCacheCapacity = 0;
469
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;
479
480         cacheMinDeadCapacity = 0;
481         cacheMaxDeadCapacity = 0;
482
483         // Foundation memory cache capacity (in bytes)
484         urlCacheMemoryCapacity = 0;
485
486         // Foundation disk cache capacity (in bytes)
487         urlCacheDiskCapacity = 0;
488
489         break;
490     }
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;
499         else
500             pageCacheCapacity = 0;
501
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;
511
512         cacheMinDeadCapacity = cacheTotalCapacity / 8;
513         cacheMaxDeadCapacity = cacheTotalCapacity / 4;
514
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;
522         else
523             urlCacheMemoryCapacity =      512 * 1024; 
524
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;
532         else
533             urlCacheDiskCapacity = 20 * 1024 * 1024;
534
535         break;
536     }
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;
548         else
549             pageCacheCapacity = 1;
550
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;
563
564         cacheMinDeadCapacity = cacheTotalCapacity / 4;
565         cacheMaxDeadCapacity = cacheTotalCapacity / 2;
566
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);
570
571         deadDecodedDataDeletionInterval = 60;
572
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;
581         else
582             urlCacheMemoryCapacity =      512 * 1024; 
583
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;
595         else
596             urlCacheDiskCapacity = 50 * 1024 * 1024;
597
598         break;
599     }
600     default:
601         ASSERT_NOT_REACHED();
602     };
603 }
604
605 WebPage* WebProcess::focusedWebPage() const
606 {    
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())
611             return page;
612     }
613     return 0;
614 }
615     
616 WebPage* WebProcess::webPage(uint64_t pageID) const
617 {
618     return m_pageMap.get(pageID).get();
619 }
620
621 void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
622 {
623 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
624     if (!m_platformSurfacePool)
625         m_platformSurfacePool = adoptPtr(new PlatformSurfacePoolTizen());
626 #endif
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);
633
634         // Balanced by an enableTermination in removeWebPage.
635         disableTermination();
636     }
637
638     ASSERT(result.iterator->second);
639 }
640
641 void WebProcess::removeWebPage(uint64_t pageID)
642 {
643     ASSERT(m_pageMap.contains(pageID));
644
645     m_pageMap.remove(pageID);
646
647 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
648     if (m_pageMap.size() == 0)
649         m_platformSurfacePool = nullptr;
650 #endif
651
652     enableTermination();
653 }
654
655 bool WebProcess::isSeparateProcess() const
656 {
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();
659 }
660  
661 bool WebProcess::shouldTerminate()
662 {
663     // Keep running forever if we're running in the same process.
664     if (!isSeparateProcess())
665         return false;
666
667     ASSERT(m_pageMap.isEmpty());
668     ASSERT(!DownloadManager::shared().isDownloading());
669
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)
673         && !shouldTerminate)
674         return false;
675
676     return true;
677 }
678
679 void WebProcess::terminate()
680 {
681 #ifndef NDEBUG
682     gcController().garbageCollectNow();
683     memoryCache()->setDisabled(true);
684 #endif
685
686     // Invalidate our connection.
687     m_connection->invalidate();
688     m_connection = nullptr;
689
690     platformTerminate();
691     m_runLoop->stop();
692 }
693
694 void WebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply)
695 {
696 #if ENABLE(TIZEN_NOTIFICATIONS)
697     if (messageID.is<CoreIPC::MessageClassWebNotificationManager>()) {
698         m_notificationManager.didReceiveSyncMessage(connection, messageID, arguments, reply);
699         return;
700     }
701 #endif
702
703 #if ENABLE(TIZEN_CACHE_DUMP_SYNC)
704     if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) {
705         WebResourceCacheManager::shared().didReceiveSyncMessage(connection, messageID, arguments, reply);
706         return;
707     }
708 #endif
709
710     uint64_t pageID = arguments->destinationID();
711     if (!pageID)
712         return;
713     
714     WebPage* page = webPage(pageID);
715     if (!page)
716         return;
717     
718     page->didReceiveSyncMessage(connection, messageID, arguments, reply);
719 }
720
721 void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
722 {
723     if (messageID.is<CoreIPC::MessageClassWebProcess>()) {
724         didReceiveWebProcessMessage(connection, messageID, arguments);
725         return;
726     }
727
728     if (messageID.is<CoreIPC::MessageClassAuthenticationManager>()) {
729         AuthenticationManager::shared().didReceiveMessage(connection, messageID, arguments);
730         return;
731     }
732
733     if (messageID.is<CoreIPC::MessageClassWebApplicationCacheManager>()) {
734         WebApplicationCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
735         return;
736     }
737
738     if (messageID.is<CoreIPC::MessageClassWebCookieManager>()) {
739         WebCookieManager::shared().didReceiveMessage(connection, messageID, arguments);
740         return;
741     }
742
743 #if ENABLE(SQL_DATABASE)
744     if (messageID.is<CoreIPC::MessageClassWebDatabaseManager>()) {
745         WebDatabaseManager::shared().didReceiveMessage(connection, messageID, arguments);
746         return;
747     }
748 #endif
749
750     if (messageID.is<CoreIPC::MessageClassWebGeolocationManager>()) {
751         m_geolocationManager.didReceiveMessage(connection, messageID, arguments);
752         return;
753     }
754
755 #if ENABLE(BATTERY_STATUS)
756     if (messageID.is<CoreIPC::MessageClassWebBatteryManager>()) {
757         m_batteryManager.didReceiveMessage(connection, messageID, arguments);
758         return;
759     }
760 #endif
761
762 #if ENABLE(NETWORK_INFO)
763     if (messageID.is<CoreIPC::MessageClassWebNetworkInfoManager>()) {
764         m_networkInfoManager.didReceiveMessage(connection, messageID, arguments);
765         return;
766     }
767 #endif
768
769     if (messageID.is<CoreIPC::MessageClassWebIconDatabaseProxy>()) {
770         m_iconDatabaseProxy.didReceiveMessage(connection, messageID, arguments);
771         return;
772     }
773
774     if (messageID.is<CoreIPC::MessageClassWebKeyValueStorageManager>()) {
775         WebKeyValueStorageManager::shared().didReceiveMessage(connection, messageID, arguments);
776         return;
777     }
778
779 #if ENABLE(TIZEN_FILE_SYSTEM)
780     if (messageID.is<CoreIPC::MessageClassWebLocalFileSystemManager>()) {
781         WebLocalFileSystemManager::shared().didReceiveMessage(connection, messageID, arguments);
782         return;
783     }
784 #endif
785
786     if (messageID.is<CoreIPC::MessageClassWebMediaCacheManager>()) {
787         WebMediaCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
788         return;
789     }
790
791 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
792     if (messageID.is<CoreIPC::MessageClassWebNotificationManager>()) {
793         m_notificationManager.didReceiveMessage(connection, messageID, arguments);
794         return;
795     }
796 #endif
797     
798     if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) {
799         WebResourceCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
800         return;
801     }
802
803 #if USE(SOUP)
804     if (messageID.is<CoreIPC::MessageClassWebSoupRequestManager>()) {
805         m_soupRequestManager.didReceiveMessage(connection, messageID, arguments);
806         return;
807     }
808 #endif
809
810     if (messageID.is<CoreIPC::MessageClassInjectedBundle>()) {
811         if (!m_injectedBundle)
812             return;
813         m_injectedBundle->didReceiveMessage(connection, messageID, arguments);    
814         return;
815     }
816
817     uint64_t pageID = arguments->destinationID();
818     if (!pageID)
819         return;
820     
821     WebPage* page = webPage(pageID);
822     if (!page)
823         return;
824     
825     page->didReceiveMessage(connection, messageID, arguments);
826 }
827
828 void WebProcess::didClose(CoreIPC::Connection*)
829 {
830     // When running in the same process the connection will never be closed.
831     ASSERT(isSeparateProcess());
832
833 #ifndef NDEBUG
834     m_inDidClose = true;
835
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)
840         pages[i]->close();
841     pages.clear();
842
843     gcController().garbageCollectSoon();
844     memoryCache()->setDisabled(true);
845 #endif    
846
847     // The UI process closed this connection, shut down.
848     m_runLoop->stop();
849 }
850
851 void WebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID)
852 {
853     // We received an invalid message, but since this is from the UI process (which we trust),
854     // we'll let it slide.
855 }
856
857 void WebProcess::syncMessageSendTimedOut(CoreIPC::Connection*)
858 {
859 }
860
861 void WebProcess::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage)
862 {
863     if (messageID.is<CoreIPC::MessageClassWebProcess>()) {
864         didReceiveWebProcessMessageOnConnectionWorkQueue(connection, messageID, arguments, didHandleMessage);
865         return;
866     }
867 }
868
869 WebFrame* WebProcess::webFrame(uint64_t frameID) const
870 {
871     return m_frameMap.get(frameID);
872 }
873
874 void WebProcess::addWebFrame(uint64_t frameID, WebFrame* frame)
875 {
876     m_frameMap.set(frameID, frame);
877 }
878
879 void WebProcess::removeWebFrame(uint64_t frameID)
880 {
881     m_frameMap.remove(frameID);
882
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.
886     if (!m_connection)
887         return;
888
889     connection()->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0);
890 }
891
892 WebPageGroupProxy* WebProcess::webPageGroup(uint64_t pageGroupID)
893 {
894     return m_pageGroupMap.get(pageGroupID).get();
895 }
896
897 WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupData)
898 {
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);
903     }
904
905     return result.iterator->second.get();
906 }
907
908 static bool canPluginHandleResponse(const ResourceResponse& response)
909 {
910     String pluginPath;
911     bool blocked;
912
913     if (!WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPluginPath(response.mimeType(), response.url().string()), Messages::WebContext::GetPluginPath::Reply(pluginPath, blocked), 0))
914         return false;
915
916     return !blocked && !pluginPath.isEmpty();
917 }
918
919 bool WebProcess::shouldUseCustomRepresentationForResponse(const ResourceResponse& response) const
920 {
921     if (!m_mimeTypesWithCustomRepresentations.contains(response.mimeType()))
922         return false;
923
924     // If a plug-in exists that claims to support this response, it should take precedence over the custom representation.
925     return !canPluginHandleResponse(response);
926 }
927
928 void WebProcess::clearResourceCaches(ResourceCachesToClear resourceCachesToClear)
929 {
930 #if ENABLE(TIZEN_CACHE_MEMORY_OPTIMIZATION)
931     if(resourceCachesToClear == InDecodedDataResourceCachesOnly) {
932         memoryCache()->removeAllDecodedData();
933         return;
934     }
935 #endif
936
937     platformClearResourceCaches(resourceCachesToClear);
938
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);
944
945     memoryCache()->evictResources();
946
947     // Empty the cross-origin preflight cache.
948     CrossOriginPreflightResultCache::shared().empty();
949 }
950
951 #if ENABLE(TIZEN_CACHE_DUMP_SYNC)
952 void WebProcess::dumpResourceCaches()
953 {
954     platformDumpResourceCaches();
955 }
956 #endif
957
958 void WebProcess::clearApplicationCache()
959 {
960     // Empty the application cache.
961     cacheStorage().empty();
962 }
963
964 #if !ENABLE(PLUGIN_PROCESS)
965 void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint64_t callbackID)
966 {
967     LocalTerminationDisabler terminationDisabler(*this);
968
969     HashSet<String> sitesSet;
970
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)
975             continue;
976
977         Vector<String> sites = netscapePluginModule->sitesWithData();
978         for (size_t i = 0; i < sites.size(); ++i)
979             sitesSet.add(sites[i]);
980     }
981 #endif
982
983     Vector<String> sites;
984     copyToVector(sitesSet, sites);
985
986     connection()->send(Messages::WebContext::DidGetSitesWithPluginData(sites, callbackID), 0);
987 }
988
989 void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID)
990 {
991     LocalTerminationDisabler terminationDisabler(*this);
992
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)
997             continue;
998
999         if (sites.isEmpty()) {
1000             // Clear everything.
1001             netscapePluginModule->clearSiteData(String(), flags, maxAgeInSeconds);
1002             continue;
1003         }
1004
1005         for (size_t i = 0; i < sites.size(); ++i)
1006             netscapePluginModule->clearSiteData(sites[i], flags, maxAgeInSeconds);
1007     }
1008 #endif
1009
1010     connection()->send(Messages::WebContext::DidClearPluginSiteData(callbackID), 0);
1011 }
1012 #endif
1013     
1014 static void fromCountedSetToHashMap(TypeCountSet* countedSet, HashMap<String, uint64_t>& map)
1015 {
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);
1019 }
1020
1021 static void getWebCoreMemoryCacheStatistics(Vector<HashMap<String, uint64_t> >& result)
1022 {
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"));
1027     
1028     MemoryCache::Statistics memoryCacheStatistics = memoryCache()->getStatistics();
1029     
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);
1036     
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);
1043     
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);
1050     
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);
1057     
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);
1064     
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);
1071 }
1072
1073 void WebProcess::getWebCoreStatistics(uint64_t callbackID)
1074 {
1075     StatisticsData data;
1076     
1077     // Gather JavaScript statistics.
1078     {
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());
1084         
1085         OwnPtr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts());
1086         fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts);
1087         
1088         OwnPtr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.objectTypeCounts());
1089         fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts);
1090         
1091         uint64_t javaScriptHeapSize = JSDOMWindow::commonJSGlobalData()->heap.size();
1092         data.statisticsNumbers.set("JavaScriptHeapSize", javaScriptHeapSize);
1093         data.statisticsNumbers.set("JavaScriptFreeSize", JSDOMWindow::commonJSGlobalData()->heap.capacity() - javaScriptHeapSize);
1094     }
1095
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);
1100     
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());
1106     
1107     // Gather font statistics.
1108     data.statisticsNumbers.set("CachedFontDataCount", fontCache()->fontDataCount());
1109     data.statisticsNumbers.set("CachedFontDataInactiveCount", fontCache()->inactiveFontDataCount());
1110     
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());
1114 #endif
1115     
1116     // Get WebCore memory cache statistics
1117     getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics);
1118     
1119     connection()->send(Messages::WebContext::DidGetWebCoreStatistics(data, callbackID), 0);
1120 }
1121
1122 void WebProcess::garbageCollectJavaScriptObjects()
1123 {
1124     gcController().garbageCollectNow();
1125 }
1126
1127 void WebProcess::setJavaScriptGarbageCollectorTimerEnabled(bool flag)
1128 {
1129     gcController().setJavaScriptGarbageCollectorTimerEnabled(flag);
1130 }
1131
1132 #if ENABLE(PLUGIN_PROCESS)
1133 void WebProcess::pluginProcessCrashed(CoreIPC::Connection*, const String& pluginPath)
1134 {
1135     m_pluginProcessConnectionManager.pluginProcessCrashed(pluginPath);
1136 }
1137 #endif
1138
1139 void WebProcess::downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, const ResourceRequest& request)
1140 {
1141     WebPage* initiatingPage = initiatingPageID ? webPage(initiatingPageID) : 0;
1142
1143     ResourceRequest requestWithOriginalURL = request;
1144     if (initiatingPage)
1145         initiatingPage->mainFrame()->loader()->setOriginalURLForDownloadRequest(requestWithOriginalURL);
1146
1147     DownloadManager::shared().startDownload(downloadID, initiatingPage, requestWithOriginalURL);
1148 }
1149
1150 void WebProcess::cancelDownload(uint64_t downloadID)
1151 {
1152     DownloadManager::shared().cancelDownload(downloadID);
1153 }
1154
1155 #if PLATFORM(QT)
1156 void WebProcess::startTransfer(uint64_t downloadID, const String& destination)
1157 {
1158     DownloadManager::shared().startTransfer(downloadID, destination);
1159 }
1160 #endif
1161
1162 void WebProcess::setEnhancedAccessibility(bool flag)
1163 {
1164     WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility(flag);
1165 }
1166     
1167 void WebProcess::startMemorySampler(const SandboxExtension::Handle& sampleLogFileHandle, const String& sampleLogFilePath, const double interval)
1168 {
1169 #if ENABLE(MEMORY_SAMPLER)    
1170     WebMemorySampler::shared()->start(sampleLogFileHandle, sampleLogFilePath, interval);
1171 #endif
1172 }
1173     
1174 void WebProcess::stopMemorySampler()
1175 {
1176 #if ENABLE(MEMORY_SAMPLER)
1177     WebMemorySampler::shared()->stop();
1178 #endif
1179 }
1180
1181 void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState)
1182 {
1183     bool continuousSpellCheckingTurnedOff = !textCheckerState.isContinuousSpellCheckingEnabled && m_textCheckerState.isContinuousSpellCheckingEnabled;
1184     bool grammarCheckingTurnedOff = !textCheckerState.isGrammarCheckingEnabled && m_textCheckerState.isGrammarCheckingEnabled;
1185
1186     m_textCheckerState = textCheckerState;
1187
1188     if (!continuousSpellCheckingTurnedOff && !grammarCheckingTurnedOff)
1189         return;
1190
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();
1198     }
1199 }
1200
1201 void WebProcess::didGetPlugins(CoreIPC::Connection*, uint64_t requestID, const Vector<WebCore::PluginInfo>& plugins)
1202 {
1203 #if USE(PLATFORM_STRATEGIES)
1204     // Pass this to WebPlatformStrategies.cpp.
1205     handleDidGetPlugins(requestID, plugins);
1206 #endif
1207 }
1208
1209 } // namespace WebKit