1 /* 2 * Copyright (C) 2007 Holger Hans Peter Freyther 3 * Copyright (C) 2008, 2010 Collabora Ltd. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21 #include "config.h" 22 #include "webkitglobals.h" 23 24 #include "ApplicationCacheStorage.h" 25 #include "Chrome.h" 26 #include "FrameNetworkingContextGtk.h" 27 #include "GOwnPtr.h" 28 #include "IconDatabase.h" 29 #include "Logging.h" 30 #include "MemoryCache.h" 31 #include "Page.h" 32 #include "PageCache.h" 33 #include "PageGroup.h" 34 #include "TextEncodingRegistry.h" 35 #include "Pasteboard.h" 36 #include "PasteboardHelperGtk.h" 37 #include "ResourceHandle.h" 38 #include "ResourceHandleClient.h" 39 #include "ResourceHandleInternal.h" 40 #include "ResourceResponse.h" 41 #include "webkitapplicationcache.h" 42 #include "webkitglobalsprivate.h" 43 #include "webkiticondatabase.h" 44 #include "webkitsoupauthdialog.h" 45 #include "webkitwebdatabase.h" 46 #include "webkitwebplugindatabaseprivate.h" 47 #include <libintl.h> 48 #include <runtime/InitializeThreading.h> 49 #include <stdlib.h> 50 #include <wtf/Threading.h> 51 52 static WebKitCacheModel cacheModel = WEBKIT_CACHE_MODEL_DEFAULT; 53 54 using namespace WebCore; 55 56 /** 57 * SECTION:webkit 58 * @short_description: Global functions controlling WebKit 59 * 60 * WebKit manages many resources which are not related to specific 61 * views. These functions relate to cross-view limits, such as cache 62 * sizes, database quotas, and the HTTP session management. 63 */ 64 65 /** 66 * webkit_get_default_session: 67 * 68 * Retrieves the default #SoupSession used by all web views. 69 * Note that the session features are added by WebKit on demand, 70 * so if you insert your own #SoupCookieJar before any network 71 * traffic occurs, WebKit will use it instead of the default. 72 * 73 * Return value: (transfer none): the default #SoupSession 74 * 75 * Since: 1.1.1 76 */ 77 SoupSession* webkit_get_default_session () 78 { 79 webkitInit(); 80 return ResourceHandle::defaultSession(); 81 } 82 83 /** 84 * webkit_set_cache_model: 85 * @cache_model: a #WebKitCacheModel 86 * 87 * Specifies a usage model for WebViews, which WebKit will use to 88 * determine its caching behavior. All web views follow the cache 89 * model. This cache model determines the RAM and disk space to use 90 * for caching previously viewed content . 91 * 92 * Research indicates that users tend to browse within clusters of 93 * documents that hold resources in common, and to revisit previously 94 * visited documents. WebKit and the frameworks below it include 95 * built-in caches that take advantage of these patterns, 96 * substantially improving document load speed in browsing 97 * situations. The WebKit cache model controls the behaviors of all of 98 * these caches, including various WebCore caches. 99 * 100 * Browsers can improve document load speed substantially by 101 * specifying WEBKIT_CACHE_MODEL_WEB_BROWSER. Applications without a 102 * browsing interface can reduce memory usage substantially by 103 * specifying WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER. Default value is 104 * WEBKIT_CACHE_MODEL_WEB_BROWSER. 105 * 106 * Since: 1.1.18 107 */ 108 void webkit_set_cache_model(WebKitCacheModel model) 109 { 110 webkitInit(); 111 112 if (cacheModel == model) 113 return; 114 115 // FIXME: Add disk cache handling when soup has the API 116 guint cacheTotalCapacity; 117 guint cacheMinDeadCapacity; 118 guint cacheMaxDeadCapacity; 119 gdouble deadDecodedDataDeletionInterval; 120 guint pageCacheCapacity; 121 122 // FIXME: The Mac port calculates these values based on the amount of physical memory that's 123 // installed on the system. Currently these values match the Mac port for users with more than 124 // 512 MB and less than 1024 MB of physical memory. 125 switch (model) { 126 case WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER: 127 pageCacheCapacity = 0; 128 cacheTotalCapacity = 0; // FIXME: The Mac port actually sets this to larger than 0. 129 cacheMinDeadCapacity = 0; 130 cacheMaxDeadCapacity = 0; 131 deadDecodedDataDeletionInterval = 0; 132 break; 133 case WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER: 134 pageCacheCapacity = 2; 135 cacheTotalCapacity = 16 * 1024 * 1024; 136 cacheMinDeadCapacity = cacheTotalCapacity / 8; 137 cacheMaxDeadCapacity = cacheTotalCapacity / 4; 138 deadDecodedDataDeletionInterval = 0; 139 break; 140 case WEBKIT_CACHE_MODEL_WEB_BROWSER: 141 // Page cache capacity (in pages). Comment from Mac port: 142 // (Research indicates that value / page drops substantially after 3 pages.) 143 pageCacheCapacity = 3; 144 cacheTotalCapacity = 32 * 1024 * 1024; 145 cacheMinDeadCapacity = cacheTotalCapacity / 4; 146 cacheMaxDeadCapacity = cacheTotalCapacity / 2; 147 deadDecodedDataDeletionInterval = 60; 148 break; 149 default: 150 g_return_if_reached(); 151 } 152 153 memoryCache()->setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity); 154 memoryCache()->setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval); 155 pageCache()->setCapacity(pageCacheCapacity); 156 cacheModel = model; 157 } 158 159 /** 160 * webkit_get_cache_model: 161 * 162 * Returns the current cache model. For more information about this 163 * value check the documentation of the function 164 * webkit_set_cache_model(). 165 * 166 * Return value: the current #WebKitCacheModel 167 * 168 * Since: 1.1.18 169 */ 170 WebKitCacheModel webkit_get_cache_model() 171 { 172 webkitInit(); 173 return cacheModel; 174 } 175 176 /** 177 * webkit_get_web_plugin_database: 178 * 179 * Returns the current #WebKitWebPluginDatabase with information about 180 * all the plugins WebKit knows about in this instance. 181 * 182 * Return value: (transfer none): the current #WebKitWebPluginDatabase 183 * 184 * Since: 1.3.8 185 */ 186 WebKitWebPluginDatabase* webkit_get_web_plugin_database() 187 { 188 static WebKitWebPluginDatabase* database = 0; 189 190 webkitInit(); 191 192 if (!database) 193 database = webkit_web_plugin_database_new(); 194 195 return database; 196 } 197 198 199 static GtkWidget* currentToplevelCallback(WebKitSoupAuthDialog* feature, SoupMessage* message, gpointer userData) 200 { 201 gpointer messageData = g_object_get_data(G_OBJECT(message), "resourceHandle"); 202 if (!messageData) 203 return NULL; 204 205 ResourceHandle* handle = static_cast<ResourceHandle*>(messageData); 206 if (!handle) 207 return NULL; 208 209 ResourceHandleInternal* d = handle->getInternal(); 210 if (!d) 211 return NULL; 212 213 WebKit::FrameNetworkingContextGtk* context = static_cast<WebKit::FrameNetworkingContextGtk*>(d->m_context.get()); 214 if (!context) 215 return NULL; 216 217 if (!context->coreFrame()) 218 return NULL; 219 220 GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(context->coreFrame()->page()->chrome()->platformPageClient())); 221 if (gtk_widget_is_toplevel(toplevel)) 222 return toplevel; 223 else 224 return NULL; 225 } 226 227 /** 228 * webkit_get_icon_database: 229 * 230 * Returns the #WebKitIconDatabase providing access to website icons. 231 * 232 * Return value: (transfer none): the current #WebKitIconDatabase 233 * 234 * Since: 1.3.13 235 */ 236 WebKitIconDatabase* webkit_get_icon_database() 237 { 238 webkitInit(); 239 240 static WebKitIconDatabase* database = 0; 241 if (!database) 242 database = WEBKIT_ICON_DATABASE(g_object_new(WEBKIT_TYPE_ICON_DATABASE, NULL)); 243 244 return database; 245 } 246 247 void webkitInit() 248 { 249 static bool isInitialized = false; 250 if (isInitialized) 251 return; 252 isInitialized = true; 253 254 bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); 255 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); 256 257 JSC::initializeThreading(); 258 WTF::initializeMainThread(); 259 260 WebCore::InitializeLoggingChannelsIfNecessary(); 261 262 // We make sure the text codecs have been initialized, because 263 // that may only be done by the main thread. 264 atomicCanonicalTextEncodingName("UTF-8"); 265 266 gchar* databaseDirectory = g_build_filename(g_get_user_data_dir(), "webkit", "databases", NULL); 267 webkit_set_web_database_directory_path(databaseDirectory); 268 WebCore::cacheStorage().setCacheDirectory(databaseDirectory); 269 270 g_free(databaseDirectory); 271 272 PageGroup::setShouldTrackVisitedLinks(true); 273 274 Pasteboard::generalPasteboard()->setHelper(WebKit::pasteboardHelperInstance()); 275 GOwnPtr<gchar> iconDatabasePath(g_build_filename(g_get_user_data_dir(), "webkit", "icondatabase", NULL)); 276 webkit_icon_database_set_path(webkit_get_icon_database(), iconDatabasePath.get()); 277 278 SoupSession* session = webkit_get_default_session(); 279 280 SoupSessionFeature* authDialog = static_cast<SoupSessionFeature*>(g_object_new(WEBKIT_TYPE_SOUP_AUTH_DIALOG, NULL)); 281 g_signal_connect(authDialog, "current-toplevel", G_CALLBACK(currentToplevelCallback), NULL); 282 soup_session_add_feature(session, authDialog); 283 g_object_unref(authDialog); 284 285 SoupSessionFeature* sniffer = static_cast<SoupSessionFeature*>(g_object_new(SOUP_TYPE_CONTENT_SNIFFER, NULL)); 286 soup_session_add_feature(session, sniffer); 287 g_object_unref(sniffer); 288 289 soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_DECODER); 290 } 291 292 namespace WebKit { 293 294 PasteboardHelperGtk* pasteboardHelperInstance() 295 { 296 static PasteboardHelperGtk* helper = new PasteboardHelperGtk(); 297 return helper; 298 } 299 300 } /** end namespace WebKit */ 301 302