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