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 54static const char* _ewk_cache_directory_path = 0; 55#endif 56 57static const char* _ewk_default_web_database_path = 0; 58static const char* _ewk_icon_database_path = 0; 59static uint64_t _ewk_default_web_database_quota = 1 * 1024 * 1024; 60 61static 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 72static 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 */ 91uint64_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 */ 102void 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 */ 124const 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 */ 141Eina_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 */ 190const 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 */ 209Eina_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 */ 230cairo_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 */ 261Evas_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 */ 284void 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 */ 310const 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 */ 334Eina_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 */ 348void 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 */ 363void 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 */ 376const 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 */ 392Eina_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 */ 418const 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