1/* 2 * Copyright (C) 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 "WebCookieManager.h" 30#include "WebPage.h" 31#include "WebProcessCreationParameters.h" 32#include <WebCore/FileSystem.h> 33#include <WebCore/MemoryCache.h> 34#include <WebCore/PageCache.h> 35#include <WebCore/Settings.h> 36#include <wtf/text/WTFString.h> 37 38#if USE(CFNETWORK) 39#include <CFNetwork/CFURLCachePriv.h> 40#include <CFNetwork/CFURLProtocolPriv.h> 41#include <WebCore/CookieStorageCFNet.h> 42#include <WebKitSystemInterface/WebKitSystemInterface.h> 43#include <wtf/RetainPtr.h> 44#endif 45 46using namespace WebCore; 47using namespace std; 48 49namespace WebKit { 50 51static uint64_t memorySize() 52{ 53 MEMORYSTATUSEX statex; 54 statex.dwLength = sizeof(statex); 55 GlobalMemoryStatusEx(&statex); 56 return statex.ullTotalPhys; 57} 58 59static uint64_t volumeFreeSize(CFStringRef cfstringPath) 60{ 61 WTF::String path(cfstringPath); 62 ULARGE_INTEGER freeBytesToCaller; 63 BOOL result = GetDiskFreeSpaceExW((LPCWSTR)path.charactersWithNullTermination(), &freeBytesToCaller, 0, 0); 64 if (!result) 65 return 0; 66 return freeBytesToCaller.QuadPart; 67} 68 69void WebProcess::platformSetCacheModel(CacheModel cacheModel) 70{ 71#if USE(CFNETWORK) 72 RetainPtr<CFStringRef> cfurlCacheDirectory(AdoptCF, wkCopyFoundationCacheDirectory()); 73 if (!cfurlCacheDirectory) 74 cfurlCacheDirectory.adoptCF(WebCore::localUserSpecificStorageDirectory().createCFString()); 75 76 // As a fudge factor, use 1000 instead of 1024, in case the reported byte 77 // count doesn't align exactly to a megabyte boundary. 78 uint64_t memSize = memorySize() / 1024 / 1000; 79 uint64_t diskFreeSize = volumeFreeSize(cfurlCacheDirectory.get()) / 1024 / 1000; 80 81 unsigned cacheTotalCapacity = 0; 82 unsigned cacheMinDeadCapacity = 0; 83 unsigned cacheMaxDeadCapacity = 0; 84 double deadDecodedDataDeletionInterval = 0; 85 unsigned pageCacheCapacity = 0; 86 unsigned long urlCacheMemoryCapacity = 0; 87 unsigned long urlCacheDiskCapacity = 0; 88 89 calculateCacheSizes(cacheModel, memSize, diskFreeSize, 90 cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval, 91 pageCacheCapacity, urlCacheMemoryCapacity, urlCacheDiskCapacity); 92 93 memoryCache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity); 94 memoryCache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval); 95 pageCache()->setCapacity(pageCacheCapacity); 96 97 RetainPtr<CFURLCacheRef> cfurlCache(AdoptCF, CFURLCacheCopySharedURLCache()); 98 CFURLCacheSetMemoryCapacity(cfurlCache.get(), urlCacheMemoryCapacity); 99 CFURLCacheSetDiskCapacity(cfurlCache.get(), max<unsigned long>(urlCacheDiskCapacity, CFURLCacheDiskCapacity(cfurlCache.get()))); // Don't shrink a big disk cache, since that would cause churn. 100#endif 101} 102 103void WebProcess::platformClearResourceCaches(ResourceCachesToClear cachesToClear) 104{ 105#if USE(CFNETWORK) 106 if (cachesToClear == InMemoryResourceCachesOnly) 107 return; 108 CFURLCacheRemoveAllCachedResponses(RetainPtr<CFURLCacheRef>(AdoptCF, CFURLCacheCopySharedURLCache()).get()); 109#endif 110} 111 112void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters& parameters, CoreIPC::ArgumentDecoder*) 113{ 114 setShouldPaintNativeControls(parameters.shouldPaintNativeControls); 115 116#if USE(CFNETWORK) 117 RetainPtr<CFStringRef> cachePath(AdoptCF, parameters.cfURLCachePath.createCFString()); 118 if (!cachePath) 119 return; 120 121 CFIndex cacheDiskCapacity = parameters.cfURLCacheDiskCapacity; 122 CFIndex cacheMemoryCapacity = parameters.cfURLCacheMemoryCapacity; 123 RetainPtr<CFURLCacheRef> uiProcessCache(AdoptCF, CFURLCacheCreate(kCFAllocatorDefault, cacheMemoryCapacity, cacheDiskCapacity, cachePath.get())); 124 CFURLCacheSetSharedURLCache(uiProcessCache.get()); 125#endif 126 127 WebCookieManager::shared().setHTTPCookieAcceptPolicy(parameters.initialHTTPCookieAcceptPolicy); 128} 129 130void WebProcess::platformTerminate() 131{ 132} 133 134void WebProcess::setShouldPaintNativeControls(bool shouldPaintNativeControls) 135{ 136#if USE(SAFARI_THEME) 137 Settings::setShouldPaintNativeControls(shouldPaintNativeControls); 138#endif 139} 140 141struct EnumWindowsContext { 142 DWORD currentThreadID; 143 Vector<HWND>* windows; 144}; 145 146static BOOL CALLBACK addWindowToVectorIfOwnedByCurrentThread(HWND window, LPARAM lParam) 147{ 148 EnumWindowsContext* context = reinterpret_cast<EnumWindowsContext*>(lParam); 149 150 if (::GetWindowThreadProcessId(window, 0) != context->currentThreadID) 151 return TRUE; 152 153 context->windows->append(window); 154 return TRUE; 155} 156 157Vector<HWND> WebProcess::windowsToReceiveSentMessagesWhileWaitingForSyncReply() 158{ 159 Vector<HWND> windows; 160 161 // Any non-message-only window created by this thread needs to receive sent messages while we 162 // wait for a sync reply. Otherwise we could deadlock with the UI process if, e.g., the focus 163 // window changes. See <http://webkit.org/b/58239>. 164 165 EnumWindowsContext context; 166 context.currentThreadID = ::GetCurrentThreadId(); 167 context.windows = &windows; 168 169 // Start out with top-level windows created by this thread (like Flash's hidden 170 // SWFlash_PlaceholderX top-level windows). 171 ::EnumThreadWindows(context.currentThreadID, addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); 172 173 // Also include any descendants of those top-level windows. 174 size_t topLevelWindowCount = windows.size(); 175 for (size_t i = 0; i < topLevelWindowCount; ++i) 176 ::EnumChildWindows(windows[i], addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); 177 178 // Also include any descendants of the WebPages' windows which we've created (e.g., for windowed plugins). 179 HashMap<uint64_t, RefPtr<WebPage> >::const_iterator::Values end = m_pageMap.end(); 180 for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator::Values it = m_pageMap.begin(); it != end; ++it) 181 ::EnumChildWindows((*it)->nativeWindow(), addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); 182 183 return windows; 184} 185 186} // namespace WebKit 187