1 /* 2 * Copyright 2007, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #define LOG_TAG "websettings" 27 28 #include <config.h> 29 #include <wtf/Platform.h> 30 31 #include "ApplicationCacheStorage.h" 32 #include "BitmapAllocatorAndroid.h" 33 #include "CachedResourceLoader.h" 34 #include "ChromiumIncludes.h" 35 #include "DatabaseTracker.h" 36 #include "Database.h" 37 #include "Document.h" 38 #include "EditorClientAndroid.h" 39 #include "FileSystem.h" 40 #include "Frame.h" 41 #include "FrameLoader.h" 42 #include "FrameView.h" 43 #include "GeolocationPermissions.h" 44 #include "GeolocationPositionCache.h" 45 #include "Page.h" 46 #include "PageCache.h" 47 #include "RenderTable.h" 48 #include "SQLiteFileSystem.h" 49 #include "Settings.h" 50 #include "WebCoreFrameBridge.h" 51 #include "WebCoreJni.h" 52 #include "WorkerContextExecutionProxy.h" 53 #include "WebRequestContext.h" 54 #include "WebViewCore.h" 55 56 #include <JNIHelp.h> 57 #include <utils/misc.h> 58 #include <wtf/text/CString.h> 59 60 namespace android { 61 62 static const int permissionFlags660 = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; 63 64 struct FieldIds { 65 FieldIds(JNIEnv* env, jclass clazz) { 66 mLayoutAlgorithm = env->GetFieldID(clazz, "mLayoutAlgorithm", 67 "Landroid/webkit/WebSettings$LayoutAlgorithm;"); 68 mTextSize = env->GetFieldID(clazz, "mTextSize", "I"); 69 mStandardFontFamily = env->GetFieldID(clazz, "mStandardFontFamily", 70 "Ljava/lang/String;"); 71 mFixedFontFamily = env->GetFieldID(clazz, "mFixedFontFamily", 72 "Ljava/lang/String;"); 73 mSansSerifFontFamily = env->GetFieldID(clazz, "mSansSerifFontFamily", 74 "Ljava/lang/String;"); 75 mSerifFontFamily = env->GetFieldID(clazz, "mSerifFontFamily", 76 "Ljava/lang/String;"); 77 mCursiveFontFamily = env->GetFieldID(clazz, "mCursiveFontFamily", 78 "Ljava/lang/String;"); 79 mFantasyFontFamily = env->GetFieldID(clazz, "mFantasyFontFamily", 80 "Ljava/lang/String;"); 81 mDefaultTextEncoding = env->GetFieldID(clazz, "mDefaultTextEncoding", 82 "Ljava/lang/String;"); 83 mUserAgent = env->GetFieldID(clazz, "mUserAgent", 84 "Ljava/lang/String;"); 85 mAcceptLanguage = env->GetFieldID(clazz, "mAcceptLanguage", "Ljava/lang/String;"); 86 mMinimumFontSize = env->GetFieldID(clazz, "mMinimumFontSize", "I"); 87 mMinimumLogicalFontSize = env->GetFieldID(clazz, "mMinimumLogicalFontSize", "I"); 88 mDefaultFontSize = env->GetFieldID(clazz, "mDefaultFontSize", "I"); 89 mDefaultFixedFontSize = env->GetFieldID(clazz, "mDefaultFixedFontSize", "I"); 90 mLoadsImagesAutomatically = env->GetFieldID(clazz, "mLoadsImagesAutomatically", "Z"); 91 #ifdef ANDROID_BLOCK_NETWORK_IMAGE 92 mBlockNetworkImage = env->GetFieldID(clazz, "mBlockNetworkImage", "Z"); 93 #endif 94 mBlockNetworkLoads = env->GetFieldID(clazz, "mBlockNetworkLoads", "Z"); 95 mJavaScriptEnabled = env->GetFieldID(clazz, "mJavaScriptEnabled", "Z"); 96 mAllowUniversalAccessFromFileURLs = env->GetFieldID(clazz, "mAllowUniversalAccessFromFileURLs", "Z"); 97 mAllowFileAccessFromFileURLs = env->GetFieldID(clazz, "mAllowFileAccessFromFileURLs", "Z"); 98 mPluginState = env->GetFieldID(clazz, "mPluginState", 99 "Landroid/webkit/WebSettings$PluginState;"); 100 #if ENABLE(DATABASE) 101 mDatabaseEnabled = env->GetFieldID(clazz, "mDatabaseEnabled", "Z"); 102 #endif 103 #if ENABLE(DOM_STORAGE) 104 mDomStorageEnabled = env->GetFieldID(clazz, "mDomStorageEnabled", "Z"); 105 #endif 106 #if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) 107 // The databases saved to disk for both the SQL and DOM Storage APIs are stored 108 // in the same base directory. 109 mDatabasePath = env->GetFieldID(clazz, "mDatabasePath", "Ljava/lang/String;"); 110 mDatabasePathHasBeenSet = env->GetFieldID(clazz, "mDatabasePathHasBeenSet", "Z"); 111 #endif 112 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 113 mAppCacheEnabled = env->GetFieldID(clazz, "mAppCacheEnabled", "Z"); 114 mAppCachePath = env->GetFieldID(clazz, "mAppCachePath", "Ljava/lang/String;"); 115 mAppCacheMaxSize = env->GetFieldID(clazz, "mAppCacheMaxSize", "J"); 116 #endif 117 #if ENABLE(WORKERS) 118 mWorkersEnabled = env->GetFieldID(clazz, "mWorkersEnabled", "Z"); 119 #endif 120 mGeolocationEnabled = env->GetFieldID(clazz, "mGeolocationEnabled", "Z"); 121 mGeolocationDatabasePath = env->GetFieldID(clazz, "mGeolocationDatabasePath", "Ljava/lang/String;"); 122 mXSSAuditorEnabled = env->GetFieldID(clazz, "mXSSAuditorEnabled", "Z"); 123 #if ENABLE(LINK_PREFETCH) 124 mLinkPrefetchEnabled = env->GetFieldID(clazz, "mLinkPrefetchEnabled", "Z"); 125 #endif 126 mJavaScriptCanOpenWindowsAutomatically = env->GetFieldID(clazz, 127 "mJavaScriptCanOpenWindowsAutomatically", "Z"); 128 mUseWideViewport = env->GetFieldID(clazz, "mUseWideViewport", "Z"); 129 mSupportMultipleWindows = env->GetFieldID(clazz, "mSupportMultipleWindows", "Z"); 130 mShrinksStandaloneImagesToFit = env->GetFieldID(clazz, "mShrinksStandaloneImagesToFit", "Z"); 131 mMaximumDecodedImageSize = env->GetFieldID(clazz, "mMaximumDecodedImageSize", "J"); 132 mPrivateBrowsingEnabled = env->GetFieldID(clazz, "mPrivateBrowsingEnabled", "Z"); 133 mSyntheticLinksEnabled = env->GetFieldID(clazz, "mSyntheticLinksEnabled", "Z"); 134 mUseDoubleTree = env->GetFieldID(clazz, "mUseDoubleTree", "Z"); 135 mPageCacheCapacity = env->GetFieldID(clazz, "mPageCacheCapacity", "I"); 136 #if ENABLE(WEB_AUTOFILL) 137 mAutoFillEnabled = env->GetFieldID(clazz, "mAutoFillEnabled", "Z"); 138 mAutoFillProfile = env->GetFieldID(clazz, "mAutoFillProfile", "Landroid/webkit/WebSettingsClassic$AutoFillProfile;"); 139 jclass autoFillProfileClass = env->FindClass("android/webkit/WebSettingsClassic$AutoFillProfile"); 140 mAutoFillProfileFullName = env->GetFieldID(autoFillProfileClass, "mFullName", "Ljava/lang/String;"); 141 mAutoFillProfileEmailAddress = env->GetFieldID(autoFillProfileClass, "mEmailAddress", "Ljava/lang/String;"); 142 mAutoFillProfileCompanyName = env->GetFieldID(autoFillProfileClass, "mCompanyName", "Ljava/lang/String;"); 143 mAutoFillProfileAddressLine1 = env->GetFieldID(autoFillProfileClass, "mAddressLine1", "Ljava/lang/String;"); 144 mAutoFillProfileAddressLine2 = env->GetFieldID(autoFillProfileClass, "mAddressLine2", "Ljava/lang/String;"); 145 mAutoFillProfileCity = env->GetFieldID(autoFillProfileClass, "mCity", "Ljava/lang/String;"); 146 mAutoFillProfileState = env->GetFieldID(autoFillProfileClass, "mState", "Ljava/lang/String;"); 147 mAutoFillProfileZipCode = env->GetFieldID(autoFillProfileClass, "mZipCode", "Ljava/lang/String;"); 148 mAutoFillProfileCountry = env->GetFieldID(autoFillProfileClass, "mCountry", "Ljava/lang/String;"); 149 mAutoFillProfilePhoneNumber = env->GetFieldID(autoFillProfileClass, "mPhoneNumber", "Ljava/lang/String;"); 150 env->DeleteLocalRef(autoFillProfileClass); 151 #endif 152 mOverrideCacheMode = env->GetFieldID(clazz, "mOverrideCacheMode", "I"); 153 mPasswordEchoEnabled = env->GetFieldID(clazz, "mPasswordEchoEnabled", "Z"); 154 155 ALOG_ASSERT(mLayoutAlgorithm, "Could not find field mLayoutAlgorithm"); 156 ALOG_ASSERT(mTextSize, "Could not find field mTextSize"); 157 ALOG_ASSERT(mStandardFontFamily, "Could not find field mStandardFontFamily"); 158 ALOG_ASSERT(mFixedFontFamily, "Could not find field mFixedFontFamily"); 159 ALOG_ASSERT(mSansSerifFontFamily, "Could not find field mSansSerifFontFamily"); 160 ALOG_ASSERT(mSerifFontFamily, "Could not find field mSerifFontFamily"); 161 ALOG_ASSERT(mCursiveFontFamily, "Could not find field mCursiveFontFamily"); 162 ALOG_ASSERT(mFantasyFontFamily, "Could not find field mFantasyFontFamily"); 163 ALOG_ASSERT(mDefaultTextEncoding, "Could not find field mDefaultTextEncoding"); 164 ALOG_ASSERT(mUserAgent, "Could not find field mUserAgent"); 165 ALOG_ASSERT(mAcceptLanguage, "Could not find field mAcceptLanguage"); 166 ALOG_ASSERT(mMinimumFontSize, "Could not find field mMinimumFontSize"); 167 ALOG_ASSERT(mMinimumLogicalFontSize, "Could not find field mMinimumLogicalFontSize"); 168 ALOG_ASSERT(mDefaultFontSize, "Could not find field mDefaultFontSize"); 169 ALOG_ASSERT(mDefaultFixedFontSize, "Could not find field mDefaultFixedFontSize"); 170 ALOG_ASSERT(mLoadsImagesAutomatically, "Could not find field mLoadsImagesAutomatically"); 171 #ifdef ANDROID_BLOCK_NETWORK_IMAGE 172 ALOG_ASSERT(mBlockNetworkImage, "Could not find field mBlockNetworkImage"); 173 #endif 174 ALOG_ASSERT(mBlockNetworkLoads, "Could not find field mBlockNetworkLoads"); 175 ALOG_ASSERT(mJavaScriptEnabled, "Could not find field mJavaScriptEnabled"); 176 ALOG_ASSERT(mAllowUniversalAccessFromFileURLs, 177 "Could not find field mAllowUniversalAccessFromFileURLs"); 178 ALOG_ASSERT(mAllowFileAccessFromFileURLs, 179 "Could not find field mAllowFileAccessFromFileURLs"); 180 ALOG_ASSERT(mPluginState, "Could not find field mPluginState"); 181 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 182 ALOG_ASSERT(mAppCacheEnabled, "Could not find field mAppCacheEnabled"); 183 ALOG_ASSERT(mAppCachePath, "Could not find field mAppCachePath"); 184 ALOG_ASSERT(mAppCacheMaxSize, "Could not find field mAppCacheMaxSize"); 185 #endif 186 #if ENABLE(WORKERS) 187 ALOG_ASSERT(mWorkersEnabled, "Could not find field mWorkersEnabled"); 188 #endif 189 ALOG_ASSERT(mJavaScriptCanOpenWindowsAutomatically, 190 "Could not find field mJavaScriptCanOpenWindowsAutomatically"); 191 ALOG_ASSERT(mUseWideViewport, "Could not find field mUseWideViewport"); 192 ALOG_ASSERT(mSupportMultipleWindows, "Could not find field mSupportMultipleWindows"); 193 ALOG_ASSERT(mShrinksStandaloneImagesToFit, "Could not find field mShrinksStandaloneImagesToFit"); 194 ALOG_ASSERT(mMaximumDecodedImageSize, "Could not find field mMaximumDecodedImageSize"); 195 ALOG_ASSERT(mUseDoubleTree, "Could not find field mUseDoubleTree"); 196 ALOG_ASSERT(mPageCacheCapacity, "Could not find field mPageCacheCapacity"); 197 ALOG_ASSERT(mPasswordEchoEnabled, "Could not find field mPasswordEchoEnabled"); 198 199 jclass enumClass = env->FindClass("java/lang/Enum"); 200 ALOG_ASSERT(enumClass, "Could not find Enum class!"); 201 mOrdinal = env->GetMethodID(enumClass, "ordinal", "()I"); 202 ALOG_ASSERT(mOrdinal, "Could not find method ordinal"); 203 env->DeleteLocalRef(enumClass); 204 } 205 206 // Field ids 207 jfieldID mLayoutAlgorithm; 208 jfieldID mTextSize; 209 jfieldID mStandardFontFamily; 210 jfieldID mFixedFontFamily; 211 jfieldID mSansSerifFontFamily; 212 jfieldID mSerifFontFamily; 213 jfieldID mCursiveFontFamily; 214 jfieldID mFantasyFontFamily; 215 jfieldID mDefaultTextEncoding; 216 jfieldID mUserAgent; 217 jfieldID mAcceptLanguage; 218 jfieldID mMinimumFontSize; 219 jfieldID mMinimumLogicalFontSize; 220 jfieldID mDefaultFontSize; 221 jfieldID mDefaultFixedFontSize; 222 jfieldID mLoadsImagesAutomatically; 223 #ifdef ANDROID_BLOCK_NETWORK_IMAGE 224 jfieldID mBlockNetworkImage; 225 #endif 226 jfieldID mBlockNetworkLoads; 227 jfieldID mJavaScriptEnabled; 228 jfieldID mAllowUniversalAccessFromFileURLs; 229 jfieldID mAllowFileAccessFromFileURLs; 230 jfieldID mPluginState; 231 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 232 jfieldID mAppCacheEnabled; 233 jfieldID mAppCachePath; 234 jfieldID mAppCacheMaxSize; 235 #endif 236 #if ENABLE(WORKERS) 237 jfieldID mWorkersEnabled; 238 #endif 239 jfieldID mJavaScriptCanOpenWindowsAutomatically; 240 jfieldID mUseWideViewport; 241 jfieldID mSupportMultipleWindows; 242 jfieldID mShrinksStandaloneImagesToFit; 243 jfieldID mMaximumDecodedImageSize; 244 jfieldID mPrivateBrowsingEnabled; 245 jfieldID mSyntheticLinksEnabled; 246 jfieldID mUseDoubleTree; 247 jfieldID mPageCacheCapacity; 248 // Ordinal() method and value field for enums 249 jmethodID mOrdinal; 250 jfieldID mTextSizeValue; 251 252 #if ENABLE(DATABASE) 253 jfieldID mDatabaseEnabled; 254 #endif 255 #if ENABLE(DOM_STORAGE) 256 jfieldID mDomStorageEnabled; 257 #endif 258 jfieldID mGeolocationEnabled; 259 jfieldID mGeolocationDatabasePath; 260 jfieldID mXSSAuditorEnabled; 261 #if ENABLE(LINK_PREFETCH) 262 jfieldID mLinkPrefetchEnabled; 263 #endif 264 #if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) 265 jfieldID mDatabasePath; 266 jfieldID mDatabasePathHasBeenSet; 267 #endif 268 #if ENABLE(WEB_AUTOFILL) 269 jfieldID mAutoFillEnabled; 270 jfieldID mAutoFillProfile; 271 jfieldID mAutoFillProfileFullName; 272 jfieldID mAutoFillProfileEmailAddress; 273 jfieldID mAutoFillProfileCompanyName; 274 jfieldID mAutoFillProfileAddressLine1; 275 jfieldID mAutoFillProfileAddressLine2; 276 jfieldID mAutoFillProfileCity; 277 jfieldID mAutoFillProfileState; 278 jfieldID mAutoFillProfileZipCode; 279 jfieldID mAutoFillProfileCountry; 280 jfieldID mAutoFillProfilePhoneNumber; 281 #endif 282 jfieldID mOverrideCacheMode; 283 jfieldID mPasswordEchoEnabled; 284 }; 285 286 static struct FieldIds* gFieldIds; 287 288 // Note: This is moved from the old FrameAndroid.cpp 289 static void recursiveCleanupForFullLayout(WebCore::RenderObject* obj) 290 { 291 obj->setNeedsLayout(true, false); 292 #ifdef ANDROID_LAYOUT 293 if (obj->isTable()) 294 (static_cast<WebCore::RenderTable *>(obj))->clearSingleColumn(); 295 #endif 296 for (WebCore::RenderObject* n = obj->firstChild(); n; n = n->nextSibling()) 297 recursiveCleanupForFullLayout(n); 298 } 299 300 #if ENABLE(WEB_AUTOFILL) 301 inline string16 getStringFieldAsString16(JNIEnv* env, jobject autoFillProfile, jfieldID fieldId) 302 { 303 jstring str = static_cast<jstring>(env->GetObjectField(autoFillProfile, fieldId)); 304 return str ? jstringToString16(env, str) : string16(); 305 } 306 307 void syncAutoFillProfile(JNIEnv* env, jobject autoFillProfile, WebAutofill* webAutofill) 308 { 309 string16 fullName = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileFullName); 310 string16 emailAddress = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileEmailAddress); 311 string16 companyName = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCompanyName); 312 string16 addressLine1 = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileAddressLine1); 313 string16 addressLine2 = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileAddressLine2); 314 string16 city = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCity); 315 string16 state = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileState); 316 string16 zipCode = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileZipCode); 317 string16 country = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCountry); 318 string16 phoneNumber = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfilePhoneNumber); 319 320 webAutofill->setProfile(fullName, emailAddress, companyName, addressLine1, addressLine2, city, state, zipCode, country, phoneNumber); 321 } 322 #endif 323 324 class WebSettings { 325 public: 326 static void Sync(JNIEnv* env, jobject obj, jint frame) 327 { 328 WebCore::Frame* pFrame = (WebCore::Frame*)frame; 329 ALOG_ASSERT(pFrame, "%s must take a valid frame pointer!", __FUNCTION__); 330 WebCore::Settings* s = pFrame->settings(); 331 if (!s) 332 return; 333 WebCore::CachedResourceLoader* cachedResourceLoader = pFrame->document()->cachedResourceLoader(); 334 335 #ifdef ANDROID_LAYOUT 336 jobject layout = env->GetObjectField(obj, gFieldIds->mLayoutAlgorithm); 337 WebCore::Settings::LayoutAlgorithm l = (WebCore::Settings::LayoutAlgorithm) 338 env->CallIntMethod(layout, gFieldIds->mOrdinal); 339 if (s->layoutAlgorithm() != l) { 340 s->setLayoutAlgorithm(l); 341 if (pFrame->document()) { 342 pFrame->document()->styleSelectorChanged(WebCore::RecalcStyleImmediately); 343 if (pFrame->document()->renderer()) { 344 recursiveCleanupForFullLayout(pFrame->document()->renderer()); 345 ALOG_ASSERT(pFrame->view(), "No view for this frame when trying to relayout"); 346 pFrame->view()->layout(); 347 // FIXME: This call used to scroll the page to put the focus into view. 348 // It worked on the WebViewCore, but now scrolling is done outside of the 349 // WebViewCore, on the UI side, so there needs to be a new way to do this. 350 //pFrame->makeFocusVisible(); 351 } 352 } 353 } 354 #endif 355 jint textSize = env->GetIntField(obj, gFieldIds->mTextSize); 356 float zoomFactor = textSize / 100.0f; 357 if (pFrame->textZoomFactor() != zoomFactor) 358 pFrame->setTextZoomFactor(zoomFactor); 359 360 jstring str = (jstring)env->GetObjectField(obj, gFieldIds->mStandardFontFamily); 361 s->setStandardFontFamily(jstringToWtfString(env, str)); 362 363 str = (jstring)env->GetObjectField(obj, gFieldIds->mFixedFontFamily); 364 s->setFixedFontFamily(jstringToWtfString(env, str)); 365 366 str = (jstring)env->GetObjectField(obj, gFieldIds->mSansSerifFontFamily); 367 s->setSansSerifFontFamily(jstringToWtfString(env, str)); 368 369 str = (jstring)env->GetObjectField(obj, gFieldIds->mSerifFontFamily); 370 s->setSerifFontFamily(jstringToWtfString(env, str)); 371 372 str = (jstring)env->GetObjectField(obj, gFieldIds->mCursiveFontFamily); 373 s->setCursiveFontFamily(jstringToWtfString(env, str)); 374 375 str = (jstring)env->GetObjectField(obj, gFieldIds->mFantasyFontFamily); 376 s->setFantasyFontFamily(jstringToWtfString(env, str)); 377 378 str = (jstring)env->GetObjectField(obj, gFieldIds->mDefaultTextEncoding); 379 s->setDefaultTextEncodingName(jstringToWtfString(env, str)); 380 381 str = (jstring)env->GetObjectField(obj, gFieldIds->mUserAgent); 382 WebFrame::getWebFrame(pFrame)->setUserAgent(jstringToWtfString(env, str)); 383 WebViewCore::getWebViewCore(pFrame->view())->setWebRequestContextUserAgent(); 384 385 jint cacheMode = env->GetIntField(obj, gFieldIds->mOverrideCacheMode); 386 WebViewCore::getWebViewCore(pFrame->view())->setWebRequestContextCacheMode(cacheMode); 387 388 str = (jstring)env->GetObjectField(obj, gFieldIds->mAcceptLanguage); 389 WebRequestContext::setAcceptLanguage(jstringToWtfString(env, str)); 390 391 jint size = env->GetIntField(obj, gFieldIds->mMinimumFontSize); 392 s->setMinimumFontSize(size); 393 394 size = env->GetIntField(obj, gFieldIds->mMinimumLogicalFontSize); 395 s->setMinimumLogicalFontSize(size); 396 397 size = env->GetIntField(obj, gFieldIds->mDefaultFontSize); 398 s->setDefaultFontSize(size); 399 400 size = env->GetIntField(obj, gFieldIds->mDefaultFixedFontSize); 401 s->setDefaultFixedFontSize(size); 402 403 jboolean flag = env->GetBooleanField(obj, gFieldIds->mLoadsImagesAutomatically); 404 s->setLoadsImagesAutomatically(flag); 405 if (flag) 406 cachedResourceLoader->setAutoLoadImages(true); 407 408 #ifdef ANDROID_BLOCK_NETWORK_IMAGE 409 flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkImage); 410 s->setBlockNetworkImage(flag); 411 if(!flag) 412 cachedResourceLoader->setBlockNetworkImage(false); 413 #endif 414 flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkLoads); 415 WebFrame* webFrame = WebFrame::getWebFrame(pFrame); 416 webFrame->setBlockNetworkLoads(flag); 417 418 flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptEnabled); 419 s->setJavaScriptEnabled(flag); 420 421 flag = env->GetBooleanField(obj, gFieldIds->mAllowUniversalAccessFromFileURLs); 422 s->setAllowUniversalAccessFromFileURLs(flag); 423 424 flag = env->GetBooleanField(obj, gFieldIds->mAllowFileAccessFromFileURLs); 425 s->setAllowFileAccessFromFileURLs(flag); 426 427 // Hyperlink auditing (the ping attribute) has similar privacy 428 // considerations as does the running of JavaScript, so to keep the UI 429 // simpler, we leverage the same setting. 430 s->setHyperlinkAuditingEnabled(flag); 431 432 // ON = 0 433 // ON_DEMAND = 1 434 // OFF = 2 435 jobject pluginState = env->GetObjectField(obj, gFieldIds->mPluginState); 436 int state = env->CallIntMethod(pluginState, gFieldIds->mOrdinal); 437 s->setPluginsEnabled(state < 2); 438 #ifdef ANDROID_PLUGINS 439 s->setPluginsOnDemand(state == 1); 440 #endif 441 442 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 443 // We only enable AppCache if it's been enabled with a call to 444 // setAppCacheEnabled() and if a valid path has been supplied to 445 // setAppCachePath(). Note that the path is applied to all WebViews 446 // whereas enabling is applied per WebView. 447 448 // WebCore asserts that the path is only set once. Since the path is 449 // shared between WebViews, we can't do the required checks to guard 450 // against this in the Java WebSettings. 451 bool isPathValid = false; 452 if (cacheStorage().cacheDirectory().isNull()) { 453 str = static_cast<jstring>(env->GetObjectField(obj, gFieldIds->mAppCachePath)); 454 // Check for non-null string as an optimization, as this is the common case. 455 if (str) { 456 String path = jstringToWtfString(env, str); 457 ALOG_ASSERT(!path.empty(), "Java side should never send empty string for AppCache path"); 458 // This database is created on the first load. If the file 459 // doesn't exist, we create it and set its permissions. The 460 // filename must match that in ApplicationCacheStorage.cpp. 461 String filename = pathByAppendingComponent(path, "ApplicationCache.db"); 462 int fd = open(filename.utf8().data(), O_CREAT, permissionFlags660); 463 if (fd >= 0) { 464 close(fd); 465 cacheStorage().setCacheDirectory(path); 466 isPathValid = true; 467 } 468 } 469 } else 470 isPathValid = true; 471 472 flag = env->GetBooleanField(obj, gFieldIds->mAppCacheEnabled); 473 s->setOfflineWebApplicationCacheEnabled(flag && isPathValid); 474 475 jlong maxsize = env->GetLongField(obj, gFieldIds->mAppCacheMaxSize); 476 cacheStorage().setMaximumSize(maxsize); 477 #endif 478 479 flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptCanOpenWindowsAutomatically); 480 s->setJavaScriptCanOpenWindowsAutomatically(flag); 481 482 #ifdef ANDROID_LAYOUT 483 flag = env->GetBooleanField(obj, gFieldIds->mUseWideViewport); 484 s->setUseWideViewport(flag); 485 #endif 486 487 #ifdef ANDROID_MULTIPLE_WINDOWS 488 flag = env->GetBooleanField(obj, gFieldIds->mSupportMultipleWindows); 489 s->setSupportMultipleWindows(flag); 490 #endif 491 flag = env->GetBooleanField(obj, gFieldIds->mShrinksStandaloneImagesToFit); 492 s->setShrinksStandaloneImagesToFit(flag); 493 jlong maxImage = env->GetLongField(obj, gFieldIds->mMaximumDecodedImageSize); 494 // Since in ImageSourceAndroid.cpp, the image will always not exceed 495 // MAX_SIZE_BEFORE_SUBSAMPLE, there's no need to pass the max value to 496 // WebCore, which checks (image_width * image_height * 4) as an 497 // estimation against the max value, which is done in CachedImage.cpp. 498 // And there're cases where the decoded image size will not 499 // exceed the max, but the WebCore estimation will. So the following 500 // code is commented out to fix those cases. 501 // if (maxImage == 0) 502 // maxImage = computeMaxBitmapSizeForCache(); 503 s->setMaximumDecodedImageSize(maxImage); 504 505 flag = env->GetBooleanField(obj, gFieldIds->mPrivateBrowsingEnabled); 506 s->setPrivateBrowsingEnabled(flag); 507 508 flag = env->GetBooleanField(obj, gFieldIds->mSyntheticLinksEnabled); 509 s->setDefaultFormatDetection(flag); 510 s->setFormatDetectionAddress(flag); 511 s->setFormatDetectionEmail(flag); 512 s->setFormatDetectionTelephone(flag); 513 #if ENABLE(DATABASE) 514 flag = env->GetBooleanField(obj, gFieldIds->mDatabaseEnabled); 515 WebCore::Database::setIsAvailable(flag); 516 517 flag = env->GetBooleanField(obj, gFieldIds->mDatabasePathHasBeenSet); 518 if (flag) { 519 // If the user has set the database path, sync it to the DatabaseTracker. 520 str = (jstring)env->GetObjectField(obj, gFieldIds->mDatabasePath); 521 if (str) { 522 String path = jstringToWtfString(env, str); 523 DatabaseTracker::tracker().setDatabaseDirectoryPath(path); 524 // This database is created when the first HTML5 Database object is 525 // instantiated. If the file doesn't exist, we create it and set its 526 // permissions. The filename must match that in 527 // DatabaseTracker.cpp. 528 String filename = SQLiteFileSystem::appendDatabaseFileNameToPath(path, "Databases.db"); 529 int fd = open(filename.utf8().data(), O_CREAT | O_EXCL, permissionFlags660); 530 if (fd >= 0) 531 close(fd); 532 } 533 } 534 #endif 535 #if ENABLE(DOM_STORAGE) 536 flag = env->GetBooleanField(obj, gFieldIds->mDomStorageEnabled); 537 s->setLocalStorageEnabled(flag); 538 str = (jstring)env->GetObjectField(obj, gFieldIds->mDatabasePath); 539 if (str) { 540 WTF::String localStorageDatabasePath = jstringToWtfString(env,str); 541 if (localStorageDatabasePath.length()) { 542 localStorageDatabasePath = WebCore::pathByAppendingComponent( 543 localStorageDatabasePath, "localstorage"); 544 // We need 770 for folders 545 mkdir(localStorageDatabasePath.utf8().data(), 546 permissionFlags660 | S_IXUSR | S_IXGRP); 547 s->setLocalStorageDatabasePath(localStorageDatabasePath); 548 } 549 } 550 #endif 551 552 flag = env->GetBooleanField(obj, gFieldIds->mGeolocationEnabled); 553 GeolocationPermissions::setAlwaysDeny(!flag); 554 str = (jstring)env->GetObjectField(obj, gFieldIds->mGeolocationDatabasePath); 555 if (str) { 556 String path = jstringToWtfString(env, str); 557 GeolocationPermissions::setDatabasePath(path); 558 GeolocationPositionCache::instance()->setDatabasePath(path); 559 // This database is created when the first Geolocation object is 560 // instantiated. If the file doesn't exist, we create it and set its 561 // permissions. The filename must match that in 562 // GeolocationPositionCache.cpp. 563 String filename = SQLiteFileSystem::appendDatabaseFileNameToPath(path, "CachedGeoposition.db"); 564 int fd = open(filename.utf8().data(), O_CREAT | O_EXCL, permissionFlags660); 565 if (fd >= 0) 566 close(fd); 567 } 568 569 flag = env->GetBooleanField(obj, gFieldIds->mXSSAuditorEnabled); 570 s->setXSSAuditorEnabled(flag); 571 572 #if ENABLE(LINK_PREFETCH) 573 flag = env->GetBooleanField(obj, gFieldIds->mLinkPrefetchEnabled); 574 s->setLinkPrefetchEnabled(flag); 575 #endif 576 577 size = env->GetIntField(obj, gFieldIds->mPageCacheCapacity); 578 if (size > 0) { 579 s->setUsesPageCache(true); 580 WebCore::pageCache()->setCapacity(size); 581 } else 582 s->setUsesPageCache(false); 583 584 #if ENABLE(WEB_AUTOFILL) 585 flag = env->GetBooleanField(obj, gFieldIds->mAutoFillEnabled); 586 // TODO: This updates the Settings WebCore side with the user's 587 // preference for autofill and will stop WebCore making requests 588 // into the chromium autofill code. That code in Chromium also has 589 // a notion of being enabled/disabled that gets read from the users 590 // preferences. At the moment, it's hardcoded to true on Android 591 // (see chrome/browser/autofill/autofill_manager.cc:405). This 592 // setting should probably be synced into Chromium also. 593 594 s->setAutoFillEnabled(flag); 595 596 if (flag) { 597 EditorClientAndroid* editorC = static_cast<EditorClientAndroid*>(pFrame->page()->editorClient()); 598 WebAutofill* webAutofill = editorC->getAutofill(); 599 // Set the active AutofillProfile data. 600 jobject autoFillProfile = env->GetObjectField(obj, gFieldIds->mAutoFillProfile); 601 if (autoFillProfile) 602 syncAutoFillProfile(env, autoFillProfile, webAutofill); 603 else { 604 // The autofill profile is null. We need to tell Chromium about this because 605 // this may be because the user just deleted their profile but left the 606 // autofill feature setting enabled. 607 webAutofill->clearProfiles(); 608 } 609 } 610 #endif 611 612 // This is required to enable the XMLTreeViewer when loading an XML document that 613 // has no style attached to it. http://trac.webkit.org/changeset/79799 614 s->setDeveloperExtrasEnabled(true); 615 s->setSpatialNavigationEnabled(true); 616 bool echoPassword = env->GetBooleanField(obj, 617 gFieldIds->mPasswordEchoEnabled); 618 s->setPasswordEchoEnabled(echoPassword); 619 } 620 }; 621 622 623 //------------------------------------------------------------- 624 // JNI registration 625 //------------------------------------------------------------- 626 627 static JNINativeMethod gWebSettingsMethods[] = { 628 { "nativeSync", "(I)V", 629 (void*) WebSettings::Sync } 630 }; 631 632 int registerWebSettings(JNIEnv* env) 633 { 634 jclass clazz = env->FindClass("android/webkit/WebSettingsClassic"); 635 ALOG_ASSERT(clazz, "Unable to find class WebSettingsClassic!"); 636 gFieldIds = new FieldIds(env, clazz); 637 env->DeleteLocalRef(clazz); 638 return jniRegisterNativeMethods(env, "android/webkit/WebSettingsClassic", 639 gWebSettingsMethods, NELEM(gWebSettingsMethods)); 640 } 641 642 } 643