Update tile partially
[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_RECORDING_SURFACE_PAINT_THREAD)
244     m_paintThreadWorkQueue = new WorkQueue("PaintThreadWorkQueue");
245 #endif
246
247 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
248     m_platformSurfacePool = adoptPtr(new PlatformSurfacePoolTizen());
249 #endif
250
251 #if ENABLE(TIZEN_JPEGIMAGE_DECODING_THREAD)
252     WebCore::AsyncImageDecoder::sharedAsyncImageDecoder();
253 #endif
254
255     startRandomCrashThreadIfRequested();
256 }
257
258 void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder* arguments)
259 {
260     ASSERT(m_pageMap.isEmpty());
261
262     platformInitializeWebProcess(parameters, arguments);
263
264     memoryPressureHandler().install();
265
266     RefPtr<APIObject> injectedBundleInitializationUserData;
267     InjectedBundleUserMessageDecoder messageDecoder(injectedBundleInitializationUserData);
268     if (!arguments->decode(messageDecoder))
269         return;
270
271     if (!parameters.injectedBundlePath.isEmpty()) {
272         m_injectedBundle = InjectedBundle::create(parameters.injectedBundlePath);
273         m_injectedBundle->setSandboxExtension(SandboxExtension::create(parameters.injectedBundlePathExtensionHandle));
274
275         if (!m_injectedBundle->load(injectedBundleInitializationUserData.get())) {
276             // Don't keep around the InjectedBundle reference if the load fails.
277             m_injectedBundle.clear();
278         }
279     }
280
281 #if ENABLE(SQL_DATABASE)
282     // Make sure the WebDatabaseManager is initialized so that the Database directory is set.
283     WebDatabaseManager::initialize(parameters.databaseDirectory);
284 #endif
285
286 #if ENABLE(ICONDATABASE)
287     m_iconDatabaseProxy.setEnabled(parameters.iconDatabaseEnabled);
288 #endif
289
290 #if ENABLE(TIZEN_FILE_SYSTEM)
291     if (WebCore::makeAllDirectories(parameters.localFileSystemDirectory))
292         WebCore::LocalFileSystem::initializeLocalFileSystem(parameters.localFileSystemDirectory);
293 #endif
294
295     StorageTracker::initializeTracker(parameters.localStorageDirectory, &WebKeyValueStorageManager::shared());
296     m_localStorageDirectory = parameters.localStorageDirectory;
297
298     if (!parameters.applicationCacheDirectory.isEmpty())
299         cacheStorage().setCacheDirectory(parameters.applicationCacheDirectory);
300
301 #if ENABLE(TIZEN_WEBKIT2_VISITED_LINKS)
302     setShouldTrackVisitedLinks(true);
303 #else
304     setShouldTrackVisitedLinks(parameters.shouldTrackVisitedLinks);
305 #endif
306     setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
307
308     if (!parameters.languages.isEmpty())
309         overrideUserPreferredLanguages(parameters.languages);
310
311     m_textCheckerState = parameters.textCheckerState;
312
313     m_fullKeyboardAccessEnabled = parameters.fullKeyboardAccessEnabled;
314
315     for (size_t i = 0; i < parameters.urlSchemesRegistererdAsEmptyDocument.size(); ++i)
316         registerURLSchemeAsEmptyDocument(parameters.urlSchemesRegistererdAsEmptyDocument[i]);
317
318     for (size_t i = 0; i < parameters.urlSchemesRegisteredAsSecure.size(); ++i)
319         registerURLSchemeAsSecure(parameters.urlSchemesRegisteredAsSecure[i]);
320
321     for (size_t i = 0; i < parameters.urlSchemesForWhichDomainRelaxationIsForbidden.size(); ++i)
322         setDomainRelaxationForbiddenForURLScheme(parameters.urlSchemesForWhichDomainRelaxationIsForbidden[i]);
323
324     setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval);
325
326     for (size_t i = 0; i < parameters.mimeTypesWithCustomRepresentation.size(); ++i)
327         m_mimeTypesWithCustomRepresentations.add(parameters.mimeTypesWithCustomRepresentation[i]);
328     
329 #if PLATFORM(MAC)
330     m_presenterApplicationPid = parameters.presenterApplicationPid;
331 #endif
332
333     if (parameters.shouldAlwaysUseComplexTextCodePath)
334         setAlwaysUsesComplexTextCodePath(true);
335
336     if (parameters.shouldUseFontSmoothing)
337         setShouldUseFontSmoothing(true);
338
339 #if USE(CFURLSTORAGESESSIONS)
340     WebCore::ResourceHandle::setPrivateBrowsingStorageSessionIdentifierBase(parameters.uiProcessBundleIdentifier);
341 #endif
342
343 #if ENABLE(PLUGIN_PROCESS)
344     m_disablePluginProcessMessageTimeout = parameters.disablePluginProcessMessageTimeout;
345 #endif
346
347 #if ENABLE(TIZEN_INDEXED_DATABASE)
348     m_indexedDatabaseDirectory = parameters.indexedDatabaseDirectory;
349 #endif
350
351 #if ENABLE(TIZEN_EXTENSIBLE_API)
352     TizenExtensibleAPI::initializeTizenExtensibleAPI();
353 #endif
354 }
355
356 void WebProcess::setShouldTrackVisitedLinks(bool shouldTrackVisitedLinks)
357 {
358     m_shouldTrackVisitedLinks = shouldTrackVisitedLinks;
359     PageGroup::setShouldTrackVisitedLinks(shouldTrackVisitedLinks);
360 }
361
362 void WebProcess::registerURLSchemeAsEmptyDocument(const String& urlScheme)
363 {
364     SchemeRegistry::registerURLSchemeAsEmptyDocument(urlScheme);
365 }
366
367 void WebProcess::registerURLSchemeAsSecure(const String& urlScheme) const
368 {
369     SchemeRegistry::registerURLSchemeAsSecure(urlScheme);
370 }
371
372 void WebProcess::setDomainRelaxationForbiddenForURLScheme(const String& urlScheme) const
373 {
374     SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(true, urlScheme);
375 }
376
377 void WebProcess::setDefaultRequestTimeoutInterval(double timeoutInterval)
378 {
379     ResourceRequest::setDefaultTimeoutInterval(timeoutInterval);
380 }
381
382 void WebProcess::setAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
383 {
384     WebCore::Font::setCodePath(alwaysUseComplexText ? WebCore::Font::Complex : WebCore::Font::Auto);
385 }
386
387 void WebProcess::setShouldUseFontSmoothing(bool useFontSmoothing)
388 {
389     WebCore::Font::setShouldUseSmoothing(useFontSmoothing);
390 }
391
392 void WebProcess::userPreferredLanguagesChanged(const Vector<String>& languages) const
393 {
394     overrideUserPreferredLanguages(languages);
395 }
396
397 void WebProcess::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
398 {
399     m_fullKeyboardAccessEnabled = fullKeyboardAccessEnabled;
400 }
401
402 void WebProcess::setVisitedLinkTable(const SharedMemory::Handle& handle)
403 {
404     RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle, SharedMemory::ReadOnly);
405     if (!sharedMemory)
406         return;
407
408     m_visitedLinkTable.setSharedMemory(sharedMemory.release());
409 }
410
411 void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes)
412 {
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]);
419     }
420
421     pageCache()->markPagesForVistedLinkStyleRecalc();
422 }
423
424 void WebProcess::allVisitedLinkStateChanged()
425 {
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()));
431
432     pageCache()->markPagesForVistedLinkStyleRecalc();
433 }
434
435 bool WebProcess::isLinkVisited(LinkHash linkHash) const
436 {
437     return m_visitedLinkTable.isLinkVisited(linkHash);
438 }
439
440 void WebProcess::addVisitedLink(WebCore::LinkHash linkHash)
441 {
442     if (isLinkVisited(linkHash) || !m_shouldTrackVisitedLinks)
443         return;
444     connection()->send(Messages::WebContext::AddVisitedLinkHash(linkHash), 0);
445 }
446
447 void WebProcess::setCacheModel(uint32_t cm)
448 {
449     CacheModel cacheModel = static_cast<CacheModel>(cm);
450
451     if (!m_hasSetCacheModel || cacheModel != m_cacheModel) {
452         m_hasSetCacheModel = true;
453         m_cacheModel = cacheModel;
454         platformSetCacheModel(cacheModel);
455     }
456 }
457
458 #if ENABLE(TIZEN_CACHE_CONTROL)
459 void WebProcess::setCacheDisabled(bool cacheDisabled)
460 {
461     platformSetCacheDisabled(cacheDisabled);
462 }
463 #endif
464
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)
468 {
469     switch (cacheModel) {
470     case CacheModelDocumentViewer: {
471         // Page cache capacity (in pages)
472         pageCacheCapacity = 0;
473
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;
483
484         cacheMinDeadCapacity = 0;
485         cacheMaxDeadCapacity = 0;
486
487         // Foundation memory cache capacity (in bytes)
488         urlCacheMemoryCapacity = 0;
489
490         // Foundation disk cache capacity (in bytes)
491         urlCacheDiskCapacity = 0;
492
493         break;
494     }
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;
503         else
504             pageCacheCapacity = 0;
505
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;
515
516         cacheMinDeadCapacity = cacheTotalCapacity / 8;
517         cacheMaxDeadCapacity = cacheTotalCapacity / 4;
518
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;
526         else
527             urlCacheMemoryCapacity =      512 * 1024; 
528
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;
536         else
537             urlCacheDiskCapacity = 20 * 1024 * 1024;
538
539         break;
540     }
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;
552         else
553             pageCacheCapacity = 1;
554
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;
567
568         cacheMinDeadCapacity = cacheTotalCapacity / 4;
569         cacheMaxDeadCapacity = cacheTotalCapacity / 2;
570
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);
574
575         deadDecodedDataDeletionInterval = 60;
576
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;
585         else
586             urlCacheMemoryCapacity =      512 * 1024; 
587
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;
599         else
600             urlCacheDiskCapacity = 50 * 1024 * 1024;
601
602         break;
603     }
604     default:
605         ASSERT_NOT_REACHED();
606     };
607 }
608
609 WebPage* WebProcess::focusedWebPage() const
610 {    
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())
615             return page;
616     }
617     return 0;
618 }
619     
620 WebPage* WebProcess::webPage(uint64_t pageID) const
621 {
622     return m_pageMap.get(pageID).get();
623 }
624
625 void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
626 {
627 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
628     if (!m_platformSurfacePool)
629         m_platformSurfacePool = adoptPtr(new PlatformSurfacePoolTizen());
630 #endif
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);
637
638         // Balanced by an enableTermination in removeWebPage.
639         disableTermination();
640     }
641
642     ASSERT(result.iterator->second);
643 }
644
645 void WebProcess::removeWebPage(uint64_t pageID)
646 {
647     ASSERT(m_pageMap.contains(pageID));
648
649     m_pageMap.remove(pageID);
650
651 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
652     if (m_pageMap.size() == 0)
653         m_platformSurfacePool = nullptr;
654 #endif
655
656     enableTermination();
657 }
658
659 bool WebProcess::isSeparateProcess() const
660 {
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();
663 }
664  
665 bool WebProcess::shouldTerminate()
666 {
667     // Keep running forever if we're running in the same process.
668     if (!isSeparateProcess())
669         return false;
670
671     ASSERT(m_pageMap.isEmpty());
672     ASSERT(!DownloadManager::shared().isDownloading());
673
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)
677         && !shouldTerminate)
678         return false;
679
680     return true;
681 }
682
683 void WebProcess::terminate()
684 {
685 #ifndef NDEBUG
686     gcController().garbageCollectNow();
687     memoryCache()->setDisabled(true);
688 #endif
689
690     // Invalidate our connection.
691     m_connection->invalidate();
692     m_connection = nullptr;
693
694     platformTerminate();
695     m_runLoop->stop();
696 }
697
698 void WebProcess::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply)
699 {
700 #if ENABLE(TIZEN_NOTIFICATIONS)
701     if (messageID.is<CoreIPC::MessageClassWebNotificationManager>()) {
702         m_notificationManager.didReceiveSyncMessage(connection, messageID, arguments, reply);
703         return;
704     }
705 #endif
706
707 #if ENABLE(TIZEN_CACHE_DUMP_SYNC)
708     if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) {
709         WebResourceCacheManager::shared().didReceiveSyncMessage(connection, messageID, arguments, reply);
710         return;
711     }
712 #endif
713
714     uint64_t pageID = arguments->destinationID();
715     if (!pageID)
716         return;
717     
718     WebPage* page = webPage(pageID);
719     if (!page)
720         return;
721     
722     page->didReceiveSyncMessage(connection, messageID, arguments, reply);
723 }
724
725 void WebProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
726 {
727     if (messageID.is<CoreIPC::MessageClassWebProcess>()) {
728         didReceiveWebProcessMessage(connection, messageID, arguments);
729         return;
730     }
731
732     if (messageID.is<CoreIPC::MessageClassAuthenticationManager>()) {
733         AuthenticationManager::shared().didReceiveMessage(connection, messageID, arguments);
734         return;
735     }
736
737     if (messageID.is<CoreIPC::MessageClassWebApplicationCacheManager>()) {
738         WebApplicationCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
739         return;
740     }
741
742     if (messageID.is<CoreIPC::MessageClassWebCookieManager>()) {
743         WebCookieManager::shared().didReceiveMessage(connection, messageID, arguments);
744         return;
745     }
746
747 #if ENABLE(SQL_DATABASE)
748     if (messageID.is<CoreIPC::MessageClassWebDatabaseManager>()) {
749         WebDatabaseManager::shared().didReceiveMessage(connection, messageID, arguments);
750         return;
751     }
752 #endif
753
754     if (messageID.is<CoreIPC::MessageClassWebGeolocationManager>()) {
755         m_geolocationManager.didReceiveMessage(connection, messageID, arguments);
756         return;
757     }
758
759 #if ENABLE(BATTERY_STATUS)
760     if (messageID.is<CoreIPC::MessageClassWebBatteryManager>()) {
761         m_batteryManager.didReceiveMessage(connection, messageID, arguments);
762         return;
763     }
764 #endif
765
766 #if ENABLE(NETWORK_INFO)
767     if (messageID.is<CoreIPC::MessageClassWebNetworkInfoManager>()) {
768         m_networkInfoManager.didReceiveMessage(connection, messageID, arguments);
769         return;
770     }
771 #endif
772
773     if (messageID.is<CoreIPC::MessageClassWebIconDatabaseProxy>()) {
774         m_iconDatabaseProxy.didReceiveMessage(connection, messageID, arguments);
775         return;
776     }
777
778     if (messageID.is<CoreIPC::MessageClassWebKeyValueStorageManager>()) {
779         WebKeyValueStorageManager::shared().didReceiveMessage(connection, messageID, arguments);
780         return;
781     }
782
783 #if ENABLE(TIZEN_FILE_SYSTEM)
784     if (messageID.is<CoreIPC::MessageClassWebLocalFileSystemManager>()) {
785         WebLocalFileSystemManager::shared().didReceiveMessage(connection, messageID, arguments);
786         return;
787     }
788 #endif
789
790     if (messageID.is<CoreIPC::MessageClassWebMediaCacheManager>()) {
791         WebMediaCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
792         return;
793     }
794
795 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
796     if (messageID.is<CoreIPC::MessageClassWebNotificationManager>()) {
797         m_notificationManager.didReceiveMessage(connection, messageID, arguments);
798         return;
799     }
800 #endif
801     
802     if (messageID.is<CoreIPC::MessageClassWebResourceCacheManager>()) {
803         WebResourceCacheManager::shared().didReceiveMessage(connection, messageID, arguments);
804         return;
805     }
806
807 #if USE(SOUP)
808     if (messageID.is<CoreIPC::MessageClassWebSoupRequestManager>()) {
809         m_soupRequestManager.didReceiveMessage(connection, messageID, arguments);
810         return;
811     }
812 #endif
813
814     if (messageID.is<CoreIPC::MessageClassInjectedBundle>()) {
815         if (!m_injectedBundle)
816             return;
817         m_injectedBundle->didReceiveMessage(connection, messageID, arguments);    
818         return;
819     }
820
821     uint64_t pageID = arguments->destinationID();
822     if (!pageID)
823         return;
824     
825     WebPage* page = webPage(pageID);
826     if (!page)
827         return;
828     
829     page->didReceiveMessage(connection, messageID, arguments);
830 }
831
832 void WebProcess::didClose(CoreIPC::Connection*)
833 {
834     // When running in the same process the connection will never be closed.
835     ASSERT(isSeparateProcess());
836
837 #ifndef NDEBUG
838     m_inDidClose = true;
839
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)
844         pages[i]->close();
845     pages.clear();
846
847     gcController().garbageCollectSoon();
848     memoryCache()->setDisabled(true);
849 #endif    
850
851     // The UI process closed this connection, shut down.
852     m_runLoop->stop();
853 }
854
855 void WebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID)
856 {
857     // We received an invalid message, but since this is from the UI process (which we trust),
858     // we'll let it slide.
859 }
860
861 void WebProcess::syncMessageSendTimedOut(CoreIPC::Connection*)
862 {
863 }
864
865 void WebProcess::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage)
866 {
867     if (messageID.is<CoreIPC::MessageClassWebProcess>()) {
868         didReceiveWebProcessMessageOnConnectionWorkQueue(connection, messageID, arguments, didHandleMessage);
869         return;
870     }
871 }
872
873 WebFrame* WebProcess::webFrame(uint64_t frameID) const
874 {
875     return m_frameMap.get(frameID);
876 }
877
878 void WebProcess::addWebFrame(uint64_t frameID, WebFrame* frame)
879 {
880     m_frameMap.set(frameID, frame);
881 }
882
883 void WebProcess::removeWebFrame(uint64_t frameID)
884 {
885     m_frameMap.remove(frameID);
886
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.
890     if (!m_connection)
891         return;
892
893     connection()->send(Messages::WebProcessProxy::DidDestroyFrame(frameID), 0);
894 }
895
896 WebPageGroupProxy* WebProcess::webPageGroup(uint64_t pageGroupID)
897 {
898     return m_pageGroupMap.get(pageGroupID).get();
899 }
900
901 WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupData)
902 {
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);
907     }
908
909     return result.iterator->second.get();
910 }
911
912 static bool canPluginHandleResponse(const ResourceResponse& response)
913 {
914     String pluginPath;
915     bool blocked;
916
917     if (!WebProcess::shared().connection()->sendSync(Messages::WebContext::GetPluginPath(response.mimeType(), response.url().string()), Messages::WebContext::GetPluginPath::Reply(pluginPath, blocked), 0))
918         return false;
919
920     return !blocked && !pluginPath.isEmpty();
921 }
922
923 bool WebProcess::shouldUseCustomRepresentationForResponse(const ResourceResponse& response) const
924 {
925     if (!m_mimeTypesWithCustomRepresentations.contains(response.mimeType()))
926         return false;
927
928     // If a plug-in exists that claims to support this response, it should take precedence over the custom representation.
929     return !canPluginHandleResponse(response);
930 }
931
932 void WebProcess::clearResourceCaches(ResourceCachesToClear resourceCachesToClear)
933 {
934 #if ENABLE(TIZEN_CACHE_MEMORY_OPTIMIZATION)
935     if(resourceCachesToClear == InDecodedDataResourceCachesOnly) {
936         memoryCache()->removeAllDecodedData();
937         return;
938     }
939 #endif
940
941     platformClearResourceCaches(resourceCachesToClear);
942
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);
948
949     memoryCache()->evictResources();
950
951     // Empty the cross-origin preflight cache.
952     CrossOriginPreflightResultCache::shared().empty();
953 }
954
955 #if ENABLE(TIZEN_CACHE_DUMP_SYNC)
956 void WebProcess::dumpResourceCaches()
957 {
958     platformDumpResourceCaches();
959 }
960 #endif
961
962 void WebProcess::clearApplicationCache()
963 {
964     // Empty the application cache.
965     cacheStorage().empty();
966 }
967
968 #if !ENABLE(PLUGIN_PROCESS)
969 void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint64_t callbackID)
970 {
971     LocalTerminationDisabler terminationDisabler(*this);
972
973     HashSet<String> sitesSet;
974
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)
979             continue;
980
981         Vector<String> sites = netscapePluginModule->sitesWithData();
982         for (size_t i = 0; i < sites.size(); ++i)
983             sitesSet.add(sites[i]);
984     }
985 #endif
986
987     Vector<String> sites;
988     copyToVector(sitesSet, sites);
989
990     connection()->send(Messages::WebContext::DidGetSitesWithPluginData(sites, callbackID), 0);
991 }
992
993 void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID)
994 {
995     LocalTerminationDisabler terminationDisabler(*this);
996
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)
1001             continue;
1002
1003         if (sites.isEmpty()) {
1004             // Clear everything.
1005             netscapePluginModule->clearSiteData(String(), flags, maxAgeInSeconds);
1006             continue;
1007         }
1008
1009         for (size_t i = 0; i < sites.size(); ++i)
1010             netscapePluginModule->clearSiteData(sites[i], flags, maxAgeInSeconds);
1011     }
1012 #endif
1013
1014     connection()->send(Messages::WebContext::DidClearPluginSiteData(callbackID), 0);
1015 }
1016 #endif
1017     
1018 static void fromCountedSetToHashMap(TypeCountSet* countedSet, HashMap<String, uint64_t>& map)
1019 {
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);
1023 }
1024
1025 static void getWebCoreMemoryCacheStatistics(Vector<HashMap<String, uint64_t> >& result)
1026 {
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"));
1031     
1032     MemoryCache::Statistics memoryCacheStatistics = memoryCache()->getStatistics();
1033     
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);
1040     
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);
1047     
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);
1054     
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);
1061     
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);
1068     
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);
1075 }
1076
1077 void WebProcess::getWebCoreStatistics(uint64_t callbackID)
1078 {
1079     StatisticsData data;
1080     
1081     // Gather JavaScript statistics.
1082     {
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());
1088         
1089         OwnPtr<TypeCountSet> protectedObjectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts());
1090         fromCountedSetToHashMap(protectedObjectTypeCounts.get(), data.javaScriptProtectedObjectTypeCounts);
1091         
1092         OwnPtr<TypeCountSet> objectTypeCounts(JSDOMWindow::commonJSGlobalData()->heap.objectTypeCounts());
1093         fromCountedSetToHashMap(objectTypeCounts.get(), data.javaScriptObjectTypeCounts);
1094         
1095         uint64_t javaScriptHeapSize = JSDOMWindow::commonJSGlobalData()->heap.size();
1096         data.statisticsNumbers.set("JavaScriptHeapSize", javaScriptHeapSize);
1097         data.statisticsNumbers.set("JavaScriptFreeSize", JSDOMWindow::commonJSGlobalData()->heap.capacity() - javaScriptHeapSize);
1098     }
1099
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);
1104     
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());
1110     
1111     // Gather font statistics.
1112     data.statisticsNumbers.set("CachedFontDataCount", fontCache()->fontDataCount());
1113     data.statisticsNumbers.set("CachedFontDataInactiveCount", fontCache()->inactiveFontDataCount());
1114     
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());
1118 #endif
1119     
1120     // Get WebCore memory cache statistics
1121     getWebCoreMemoryCacheStatistics(data.webCoreCacheStatistics);
1122     
1123     connection()->send(Messages::WebContext::DidGetWebCoreStatistics(data, callbackID), 0);
1124 }
1125
1126 void WebProcess::garbageCollectJavaScriptObjects()
1127 {
1128     gcController().garbageCollectNow();
1129 }
1130
1131 void WebProcess::setJavaScriptGarbageCollectorTimerEnabled(bool flag)
1132 {
1133     gcController().setJavaScriptGarbageCollectorTimerEnabled(flag);
1134 }
1135
1136 #if ENABLE(PLUGIN_PROCESS)
1137 void WebProcess::pluginProcessCrashed(CoreIPC::Connection*, const String& pluginPath)
1138 {
1139     m_pluginProcessConnectionManager.pluginProcessCrashed(pluginPath);
1140 }
1141 #endif
1142
1143 void WebProcess::downloadRequest(uint64_t downloadID, uint64_t initiatingPageID, const ResourceRequest& request)
1144 {
1145     WebPage* initiatingPage = initiatingPageID ? webPage(initiatingPageID) : 0;
1146
1147     ResourceRequest requestWithOriginalURL = request;
1148     if (initiatingPage)
1149         initiatingPage->mainFrame()->loader()->setOriginalURLForDownloadRequest(requestWithOriginalURL);
1150
1151     DownloadManager::shared().startDownload(downloadID, initiatingPage, requestWithOriginalURL);
1152 }
1153
1154 void WebProcess::cancelDownload(uint64_t downloadID)
1155 {
1156     DownloadManager::shared().cancelDownload(downloadID);
1157 }
1158
1159 #if PLATFORM(QT)
1160 void WebProcess::startTransfer(uint64_t downloadID, const String& destination)
1161 {
1162     DownloadManager::shared().startTransfer(downloadID, destination);
1163 }
1164 #endif
1165
1166 void WebProcess::setEnhancedAccessibility(bool flag)
1167 {
1168     WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility(flag);
1169 }
1170     
1171 void WebProcess::startMemorySampler(const SandboxExtension::Handle& sampleLogFileHandle, const String& sampleLogFilePath, const double interval)
1172 {
1173 #if ENABLE(MEMORY_SAMPLER)    
1174     WebMemorySampler::shared()->start(sampleLogFileHandle, sampleLogFilePath, interval);
1175 #endif
1176 }
1177     
1178 void WebProcess::stopMemorySampler()
1179 {
1180 #if ENABLE(MEMORY_SAMPLER)
1181     WebMemorySampler::shared()->stop();
1182 #endif
1183 }
1184
1185 void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState)
1186 {
1187     bool continuousSpellCheckingTurnedOff = !textCheckerState.isContinuousSpellCheckingEnabled && m_textCheckerState.isContinuousSpellCheckingEnabled;
1188     bool grammarCheckingTurnedOff = !textCheckerState.isGrammarCheckingEnabled && m_textCheckerState.isGrammarCheckingEnabled;
1189
1190     m_textCheckerState = textCheckerState;
1191
1192     if (!continuousSpellCheckingTurnedOff && !grammarCheckingTurnedOff)
1193         return;
1194
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();
1202     }
1203 }
1204
1205 void WebProcess::didGetPlugins(CoreIPC::Connection*, uint64_t requestID, const Vector<WebCore::PluginInfo>& plugins)
1206 {
1207 #if USE(PLATFORM_STRATEGIES)
1208     // Pass this to WebPlatformStrategies.cpp.
1209     handleDidGetPlugins(requestID, plugins);
1210 #endif
1211 }
1212
1213 } // namespace WebKit