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 */
webkit_get_default_session()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 */
webkit_set_cache_model(WebKitCacheModel model)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 */
webkit_get_cache_model()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 */
webkit_get_web_plugin_database()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
currentToplevelCallback(WebKitSoupAuthDialog * feature,SoupMessage * message,gpointer userData)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 */
webkit_get_icon_database()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
webkitInit()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
pasteboardHelperInstance()294 PasteboardHelperGtk* pasteboardHelperInstance()
295 {
296 static PasteboardHelperGtk* helper = new PasteboardHelperGtk();
297 return helper;
298 }
299
300 } /** end namespace WebKit */
301
302