23504f2c968dd1287ac1d9b985800ca80fc7ebc9
[WebKit-https.git] / Source / WebKit / efl / ewk / ewk_settings.cpp
1 /*
2     Copyright (C) 2009-2010 ProFUSION embedded systems
3     Copyright (C) 2009-2010 Samsung Electronics
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 "ewk_settings.h"
23
24 #include "EWebKit.h"
25 #if ENABLE(DATABASE)
26 #include "DatabaseTracker.h"
27 #endif
28 #include "FrameView.h"
29 #include "IconDatabase.h"
30 #include "Image.h"
31 #include "IntSize.h"
32 #include "KURL.h"
33 #include "MemoryCache.h"
34 #include "ewk_private.h"
35
36 #include <Eina.h>
37 #include <eina_safety_checks.h>
38 #include <errno.h>
39 #include <string.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 #include <sys/utsname.h>
43 #include <unistd.h>
44 #include <wtf/text/CString.h>
45 #include <wtf/text/StringConcatenate.h>
46
47 #if USE(SOUP)
48 #include "ResourceHandle.h"
49 #include <libsoup/soup.h>
50 #endif
51
52 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
53 #include "appcache/ApplicationCacheStorage.h"
54
55 static const char* _ewk_cache_directory_path = 0;
56 #endif
57
58 static const char* _ewk_icon_database_path = 0;
59 #if ENABLE(DATABASE)
60 static const char* _ewk_default_web_database_path = 0;
61 static uint64_t _ewk_default_web_database_quota = 1 * 1024 * 1024;
62 #endif
63
64 static WTF::String _ewk_settings_webkit_platform_get()
65 {
66     WTF::String ua_platform;
67 #if PLATFORM(X11)
68     ua_platform = "X11";
69 #else
70     ua_platform = "Unknown";
71 #endif
72     return ua_platform;
73 }
74
75 static WTF::String _ewk_settings_webkit_os_version_get()
76 {
77     WTF::String ua_os_version;
78     struct utsname name;
79
80     if (uname(&name) != -1)
81         ua_os_version = makeString(name.sysname, ' ', name.machine);
82     else
83         ua_os_version = "Unknown";
84
85     return ua_os_version;
86 }
87
88 /**
89  * Returns the default quota for Web Database databases. By default
90  * this value is 1MB.
91  *
92  * @return the current default database quota in bytes
93  */
94 uint64_t ewk_settings_web_database_default_quota_get(void)
95 {
96 #if ENABLE(DATABASE)
97     return _ewk_default_web_database_quota;
98 #else
99     return 0;
100 #endif
101 }
102
103 /**
104  * Sets the current path to the directory WebKit will write Web
105  * Database databases.
106  *
107  * @param path the new database directory path
108  */
109 void ewk_settings_web_database_path_set(const char *path)
110 {
111 #if ENABLE(DATABASE)
112     WTF::String corePath = WTF::String::fromUTF8(path);
113     WebCore::DatabaseTracker::tracker().setDatabaseDirectoryPath(corePath);
114     if (!_ewk_default_web_database_path)
115         _ewk_default_web_database_path = eina_stringshare_add(corePath.utf8().data());
116     else
117         eina_stringshare_replace(&_ewk_default_web_database_path, corePath.utf8().data());
118
119 #endif
120 }
121
122 /**
123  * Returns directory path where web database is stored.
124  *
125  * This is guaranteed to be eina_stringshare, so whenever possible
126  * save yourself some cpu cycles and use eina_stringshare_ref()
127  * instead of eina_stringshare_add() or strdup().
128  *
129  * @return database path or @c 0 if none or web database is not supported
130  */
131 const char *ewk_settings_web_database_path_get(void)
132 {
133 #if ENABLE(DATABASE)
134     return _ewk_default_web_database_path;
135 #else
136     return 0;
137 #endif
138 }
139
140 /**
141  * Sets directory where to store icon database, opening or closing database.
142  *
143  * @param directory where to store icon database, must be
144  *        write-able, if @c 0 is given, then database is closed
145  *
146  * @return @c EINA_TRUE on success, @c EINA_FALSE on errors
147  */
148 Eina_Bool ewk_settings_icon_database_path_set(const char *directory)
149 {
150     WebCore::IconDatabase::delayDatabaseCleanup();
151
152     if (directory) {
153         struct stat st;
154
155         if (stat(directory, &st)) {
156             ERR("could not stat(%s): %s", directory, strerror(errno));
157             return EINA_FALSE;
158         }
159
160         if (!S_ISDIR(st.st_mode)) {
161             ERR("not a directory: %s", directory);
162             return EINA_FALSE;
163         }
164
165         if (access(directory, R_OK | W_OK)) {
166             ERR("could not access directory '%s' for read and write: %s",
167                 directory, strerror(errno));
168             return EINA_FALSE;
169         }
170
171         WebCore::iconDatabase().setEnabled(true);
172         WebCore::iconDatabase().open(WTF::String::fromUTF8(directory), WebCore::IconDatabase::defaultDatabaseFilename());
173         if (!_ewk_icon_database_path)
174             _ewk_icon_database_path = eina_stringshare_add(directory);
175         else
176             eina_stringshare_replace(&_ewk_icon_database_path, directory);
177     } else {
178         WebCore::iconDatabase().setEnabled(false);
179         WebCore::iconDatabase().close();
180         if (_ewk_icon_database_path) {
181             eina_stringshare_del(_ewk_icon_database_path);
182             _ewk_icon_database_path = 0;
183         }
184     }
185     return EINA_TRUE;
186 }
187
188 /**
189  * Returns directory path where icon database is stored.
190  *
191  * This is guaranteed to be eina_stringshare, so whenever possible
192  * save yourself some cpu cycles and use eina_stringshare_ref()
193  * instead of eina_stringshare_add() or strdup().
194  *
195  * @return database path or @c 0 if none is set or database is closed
196  */
197 const char* ewk_settings_icon_database_path_get(void)
198 {
199     if (!WebCore::iconDatabase().isEnabled())
200         return 0;
201     if (!WebCore::iconDatabase().isOpen())
202         return 0;
203
204     return _ewk_icon_database_path;
205 }
206
207 /**
208  * Removes all known icons from database.
209  *
210  * Database must be opened with ewk_settings_icon_database_path_set()
211  * in order to work.
212  *
213  * @return @c EINA_TRUE on success or @c EINA_FALSE otherwise, like
214  *         closed database.
215  */
216 Eina_Bool ewk_settings_icon_database_clear(void)
217 {
218     if (!WebCore::iconDatabase().isEnabled())
219         return EINA_FALSE;
220     if (!WebCore::iconDatabase().isOpen())
221         return EINA_FALSE;
222
223     WebCore::iconDatabase().removeAllIcons();
224     return EINA_TRUE;
225 }
226
227 /**
228  * Queries icon for given URL, returning associated cairo surface.
229  *
230  * @note In order to have this working, one must open icon database
231  *       with ewk_settings_icon_database_path_set().
232  *
233  * @param url which url to query icon
234  *
235  * @return cairo surface if any, or @c 0 on failure
236  */
237 cairo_surface_t* ewk_settings_icon_database_icon_surface_get(const char *url)
238 {
239     EINA_SAFETY_ON_NULL_RETURN_VAL(url, 0);
240
241     WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(url));
242     WebCore::Image *icon = WebCore::iconDatabase().synchronousIconForPageURL(kurl.string(), WebCore::IntSize(16, 16));
243
244     if (!icon) {
245         ERR("no icon for url %s", url);
246         return 0;
247     }
248
249     return icon->nativeImageForCurrentFrame();
250 }
251
252 /**
253  * Creates Evas_Object of type image representing the given URL.
254  *
255  * This is an utility function that creates an Evas_Object of type
256  * image set to have fill always match object size
257  * (evas_object_image_filled_add()), saving some code to use it from Evas.
258  *
259  * @note In order to have this working, one must open icon database
260  *       with ewk_settings_icon_database_path_set().
261  *
262  * @param url which url to query icon
263  * @param canvas evas instance where to add resulting object
264  *
265  * @return newly allocated Evas_Object instance or @c 0 on
266  *         errors. Delete the object with evas_object_del().
267  */
268 Evas_Object* ewk_settings_icon_database_icon_object_add(const char* url, Evas* canvas)
269 {
270     EINA_SAFETY_ON_NULL_RETURN_VAL(url, 0);
271     EINA_SAFETY_ON_NULL_RETURN_VAL(canvas, 0);
272
273     WebCore::KURL kurl(WebCore::KURL(), WTF::String::fromUTF8(url));
274     WebCore::Image* icon = WebCore::iconDatabase().synchronousIconForPageURL(kurl.string(), WebCore::IntSize(16, 16));
275     cairo_surface_t* surface;
276
277     if (!icon) {
278         ERR("no icon for url %s", url);
279         return 0;
280     }
281
282     surface = icon->nativeImageForCurrentFrame();
283     return ewk_util_image_from_cairo_surface_add(canvas, surface);
284 }
285
286 /**
287  * Sets the given proxy URI to network backend.
288  *
289  * @param proxy URI to set
290  */
291 void ewk_settings_proxy_uri_set(const char* proxy)
292 {
293 #if USE(SOUP)
294     SoupSession* session = WebCore::ResourceHandle::defaultSession();
295
296     if (!proxy) {
297         ERR("no proxy uri. remove proxy feature in soup.");
298         soup_session_remove_feature_by_type(session, SOUP_TYPE_PROXY_RESOLVER);
299         return;
300     }
301
302     SoupURI* uri = soup_uri_new(proxy);
303     EINA_SAFETY_ON_NULL_RETURN(uri);
304
305     g_object_set(session, SOUP_SESSION_PROXY_URI, uri, NULL);
306     soup_uri_free(uri);
307 #elif USE(CURL)
308     EINA_SAFETY_ON_TRUE_RETURN(1);
309 #endif
310 }
311
312 /**
313  * Gets the proxy URI from the network backend.
314  *
315  * @return current proxy URI or @c 0 if it's not set
316  */
317 const char* ewk_settings_proxy_uri_get(void)
318 {
319 #if USE(SOUP)
320     SoupURI* uri;
321     SoupSession* session = WebCore::ResourceHandle::defaultSession();
322     g_object_get(session, SOUP_SESSION_PROXY_URI, &uri, NULL);
323
324     if (!uri) {
325         ERR("no proxy uri");
326         return 0;
327     }
328
329     WTF::String proxy = soup_uri_to_string(uri, EINA_FALSE);
330     return eina_stringshare_add(proxy.utf8().data());
331 #elif USE(CURL)
332     EINA_SAFETY_ON_TRUE_RETURN_VAL(1, 0);
333 #endif
334 }
335
336 /**
337  * Gets status of the memory cache of WebCore.
338  *
339  * @return @c EINA_TRUE if the cache is enabled or @c EINA_FALSE if not
340  */
341 Eina_Bool ewk_settings_cache_enable_get(void)
342 {
343     WebCore::MemoryCache* cache = WebCore::memoryCache();
344     return !cache->disabled();
345 }
346
347 /**
348  * Enables/disables the memory cache of WebCore, possibly clearing it.
349  *
350  * Disabling the cache will remove all resources from the cache.
351  * They may still live on if they are referenced by some Web page though.
352  *
353  * @param set @c EINA_TRUE to enable memory cache, @c EINA_FALSE to disable
354  */
355 void ewk_settings_cache_enable_set(Eina_Bool set)
356 {
357     WebCore::MemoryCache* cache = WebCore::memoryCache();
358     set = !set;
359     if (cache->disabled() != set)
360         cache->setDisabled(set);
361 }
362
363 /**
364  * Sets capacity of memory cache of WebCore.
365  *
366  * WebCore sets default value of memory cache on 8192 * 1024 bytes.
367  *
368  * @param capacity the maximum number of bytes that the cache should consume overall
369  */
370 void ewk_settings_cache_capacity_set(unsigned capacity)
371 {
372     WebCore::MemoryCache* cache = WebCore::memoryCache();
373     cache->setCapacities(0, capacity, capacity);
374 }
375
376 /**
377  * Sets values for repaint throttling.
378  *
379  * It allows to slow down page loading and
380  * should ensure displaying a content with many css/gif animations.
381  *
382  * These values can be used as a example for repaints throttling.
383  * 0,     0,   0,    0    - default WebCore's values, these do not delay any repaints
384  * 0.025, 0,   2.5,  0.5  - recommended values for dynamic content
385  * 0.01,  0,   1,    0.2  - minimal level
386  * 0.025, 1,   5,    0.5  - medium level
387  * 0.1,   2,   10,   1    - heavy level
388  *
389  * @param deferred_repaint_delay a normal delay
390  * @param initial_deferred_repaint_delay_during_loading negative value would mean that first few repaints happen without a delay
391  * @param max_deferred_repaint_delay_during_loading the delay grows on each repaint to this maximum value
392  * @param deferred_repaint_delay_increment_during_loading on each repaint the delay increses by this amount
393  */
394 void ewk_settings_repaint_throttling_set(double deferred_repaint_delay, double initial_deferred_repaint_delay_during_loading, double max_deferred_repaint_delay_during_loading, double deferred_repaint_delay_increment_during_loading)
395 {
396     WebCore::FrameView::setRepaintThrottlingDeferredRepaintDelay(deferred_repaint_delay);
397     WebCore::FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(initial_deferred_repaint_delay_during_loading);
398     WebCore::FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(max_deferred_repaint_delay_during_loading);
399     WebCore::FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(deferred_repaint_delay_increment_during_loading);
400 }
401
402 /**
403  * @internal
404  *
405  * Gets the default user agent string.
406  *
407  * @return a pointer to an eina_stringshare containing the user agent string
408  */
409 const char* ewk_settings_default_user_agent_get(void)
410 {
411     WTF::String ua_version = makeString(String::number(WEBKIT_USER_AGENT_MAJOR_VERSION), '.', String::number(WEBKIT_USER_AGENT_MINOR_VERSION), '+');
412     WTF::String static_ua = makeString("Mozilla/5.0 (", _ewk_settings_webkit_platform_get(), "; ", _ewk_settings_webkit_os_version_get(), ") AppleWebKit/", ua_version) + makeString(" (KHTML, like Gecko) Version/5.0 Safari/", ua_version);
413
414     return eina_stringshare_add(static_ua.utf8().data());
415 }
416
417 /**
418  * Sets cache directory.
419  *
420  * @param path where to store cache, must be write-able.
421  *
422  * @return @c EINA_TRUE on success, @c EINA_FALSE if path is NULL or offline
423  *         web application is not supported.
424  */
425 Eina_Bool ewk_settings_cache_directory_path_set(const char *path)
426 {
427 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
428     if (!path)
429         return EINA_FALSE;
430
431     WebCore::cacheStorage().setCacheDirectory(WTF::String::fromUTF8(path));
432     if (!_ewk_cache_directory_path)
433         _ewk_cache_directory_path = eina_stringshare_add(path);
434     else
435         eina_stringshare_replace(&_ewk_cache_directory_path, path);
436     return EINA_TRUE;
437 #else
438     EINA_SAFETY_ON_TRUE_RETURN_VAL(1, EINA_FALSE);
439 #endif
440 }
441
442 /**
443  * Return cache directory path.
444  *
445  * This is guaranteed to be eina_stringshare, so whenever possible
446  * save yourself some cpu cycles and use eina_stringshare_ref()
447  * instead of eina_stringshare_add() or strdup().
448  *
449  * @return cache directory path.
450  */
451 const char *ewk_settings_cache_directory_path_get()
452 {
453 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
454     return _ewk_cache_directory_path;
455 #else
456     EINA_SAFETY_ON_TRUE_RETURN_VAL(1, 0);
457 #endif
458 }