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 mGetUserAgentString = env->GetMethodID(clazz, "getUserAgentString", 84 "()Ljava/lang/String;"); 85 mGetAcceptLanguage = env->GetMethodID(clazz, "getAcceptLanguage", "()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 mMediaPlaybackRequiresUserGesture = env->GetFieldID(clazz, "mMediaPlaybackRequiresUserGesture", "Z"); 155 156 ALOG_ASSERT(mLayoutAlgorithm, "Could not find field mLayoutAlgorithm"); 157 ALOG_ASSERT(mTextSize, "Could not find field mTextSize"); 158 ALOG_ASSERT(mStandardFontFamily, "Could not find field mStandardFontFamily"); 159 ALOG_ASSERT(mFixedFontFamily, "Could not find field mFixedFontFamily"); 160 ALOG_ASSERT(mSansSerifFontFamily, "Could not find field mSansSerifFontFamily"); 161 ALOG_ASSERT(mSerifFontFamily, "Could not find field mSerifFontFamily"); 162 ALOG_ASSERT(mCursiveFontFamily, "Could not find field mCursiveFontFamily"); 163 ALOG_ASSERT(mFantasyFontFamily, "Could not find field mFantasyFontFamily"); 164 ALOG_ASSERT(mDefaultTextEncoding, "Could not find field mDefaultTextEncoding"); 165 ALOG_ASSERT(mGetUserAgentString, "Could not find method getUserAgentString"); 166 ALOG_ASSERT(mGetAcceptLanguage, "Could not find method getAcceptLanguage"); 167 ALOG_ASSERT(mMinimumFontSize, "Could not find field mMinimumFontSize"); 168 ALOG_ASSERT(mMinimumLogicalFontSize, "Could not find field mMinimumLogicalFontSize"); 169 ALOG_ASSERT(mDefaultFontSize, "Could not find field mDefaultFontSize"); 170 ALOG_ASSERT(mDefaultFixedFontSize, "Could not find field mDefaultFixedFontSize"); 171 ALOG_ASSERT(mLoadsImagesAutomatically, "Could not find field mLoadsImagesAutomatically"); 172 #ifdef ANDROID_BLOCK_NETWORK_IMAGE 173 ALOG_ASSERT(mBlockNetworkImage, "Could not find field mBlockNetworkImage"); 174 #endif 175 ALOG_ASSERT(mBlockNetworkLoads, "Could not find field mBlockNetworkLoads"); 176 ALOG_ASSERT(mJavaScriptEnabled, "Could not find field mJavaScriptEnabled"); 177 ALOG_ASSERT(mAllowUniversalAccessFromFileURLs, 178 "Could not find field mAllowUniversalAccessFromFileURLs"); 179 ALOG_ASSERT(mAllowFileAccessFromFileURLs, 180 "Could not find field mAllowFileAccessFromFileURLs"); 181 ALOG_ASSERT(mPluginState, "Could not find field mPluginState"); 182 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 183 ALOG_ASSERT(mAppCacheEnabled, "Could not find field mAppCacheEnabled"); 184 ALOG_ASSERT(mAppCachePath, "Could not find field mAppCachePath"); 185 ALOG_ASSERT(mAppCacheMaxSize, "Could not find field mAppCacheMaxSize"); 186 #endif 187 #if ENABLE(WORKERS) 188 ALOG_ASSERT(mWorkersEnabled, "Could not find field mWorkersEnabled"); 189 #endif 190 ALOG_ASSERT(mJavaScriptCanOpenWindowsAutomatically, 191 "Could not find field mJavaScriptCanOpenWindowsAutomatically"); 192 ALOG_ASSERT(mUseWideViewport, "Could not find field mUseWideViewport"); 193 ALOG_ASSERT(mSupportMultipleWindows, "Could not find field mSupportMultipleWindows"); 194 ALOG_ASSERT(mShrinksStandaloneImagesToFit, "Could not find field mShrinksStandaloneImagesToFit"); 195 ALOG_ASSERT(mMaximumDecodedImageSize, "Could not find field mMaximumDecodedImageSize"); 196 ALOG_ASSERT(mUseDoubleTree, "Could not find field mUseDoubleTree"); 197 ALOG_ASSERT(mPageCacheCapacity, "Could not find field mPageCacheCapacity"); 198 ALOG_ASSERT(mPasswordEchoEnabled, "Could not find field mPasswordEchoEnabled"); 199 ALOG_ASSERT(mMediaPlaybackRequiresUserGesture, "Could not find field mMediaPlaybackRequiresUserGesture"); 200 201 jclass enumClass = env->FindClass("java/lang/Enum"); 202 ALOG_ASSERT(enumClass, "Could not find Enum class!"); 203 mOrdinal = env->GetMethodID(enumClass, "ordinal", "()I"); 204 ALOG_ASSERT(mOrdinal, "Could not find method ordinal"); 205 env->DeleteLocalRef(enumClass); 206 } 207 208 // Field ids 209 jfieldID mLayoutAlgorithm; 210 jfieldID mTextSize; 211 jfieldID mStandardFontFamily; 212 jfieldID mFixedFontFamily; 213 jfieldID mSansSerifFontFamily; 214 jfieldID mSerifFontFamily; 215 jfieldID mCursiveFontFamily; 216 jfieldID mFantasyFontFamily; 217 jfieldID mDefaultTextEncoding; 218 jmethodID mGetUserAgentString; 219 jmethodID mGetAcceptLanguage; 220 jfieldID mMinimumFontSize; 221 jfieldID mMinimumLogicalFontSize; 222 jfieldID mDefaultFontSize; 223 jfieldID mDefaultFixedFontSize; 224 jfieldID mLoadsImagesAutomatically; 225 #ifdef ANDROID_BLOCK_NETWORK_IMAGE 226 jfieldID mBlockNetworkImage; 227 #endif 228 jfieldID mBlockNetworkLoads; 229 jfieldID mJavaScriptEnabled; 230 jfieldID mAllowUniversalAccessFromFileURLs; 231 jfieldID mAllowFileAccessFromFileURLs; 232 jfieldID mPluginState; 233 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 234 jfieldID mAppCacheEnabled; 235 jfieldID mAppCachePath; 236 jfieldID mAppCacheMaxSize; 237 #endif 238 #if ENABLE(WORKERS) 239 jfieldID mWorkersEnabled; 240 #endif 241 jfieldID mJavaScriptCanOpenWindowsAutomatically; 242 jfieldID mUseWideViewport; 243 jfieldID mSupportMultipleWindows; 244 jfieldID mShrinksStandaloneImagesToFit; 245 jfieldID mMaximumDecodedImageSize; 246 jfieldID mPrivateBrowsingEnabled; 247 jfieldID mSyntheticLinksEnabled; 248 jfieldID mUseDoubleTree; 249 jfieldID mPageCacheCapacity; 250 // Ordinal() method and value field for enums 251 jmethodID mOrdinal; 252 jfieldID mTextSizeValue; 253 254 #if ENABLE(DATABASE) 255 jfieldID mDatabaseEnabled; 256 #endif 257 #if ENABLE(DOM_STORAGE) 258 jfieldID mDomStorageEnabled; 259 #endif 260 jfieldID mGeolocationEnabled; 261 jfieldID mGeolocationDatabasePath; 262 jfieldID mXSSAuditorEnabled; 263 #if ENABLE(LINK_PREFETCH) 264 jfieldID mLinkPrefetchEnabled; 265 #endif 266 #if ENABLE(DATABASE) || ENABLE(DOM_STORAGE) 267 jfieldID mDatabasePath; 268 jfieldID mDatabasePathHasBeenSet; 269 #endif 270 #if ENABLE(WEB_AUTOFILL) 271 jfieldID mAutoFillEnabled; 272 jfieldID mAutoFillProfile; 273 jfieldID mAutoFillProfileFullName; 274 jfieldID mAutoFillProfileEmailAddress; 275 jfieldID mAutoFillProfileCompanyName; 276 jfieldID mAutoFillProfileAddressLine1; 277 jfieldID mAutoFillProfileAddressLine2; 278 jfieldID mAutoFillProfileCity; 279 jfieldID mAutoFillProfileState; 280 jfieldID mAutoFillProfileZipCode; 281 jfieldID mAutoFillProfileCountry; 282 jfieldID mAutoFillProfilePhoneNumber; 283 #endif 284 jfieldID mOverrideCacheMode; 285 jfieldID mPasswordEchoEnabled; 286 jfieldID mMediaPlaybackRequiresUserGesture; 287 }; 288 289 static struct FieldIds* gFieldIds; 290 291 // Note: This is moved from the old FrameAndroid.cpp 292 static void recursiveCleanupForFullLayout(WebCore::RenderObject* obj) 293 { 294 obj->setNeedsLayout(true, false); 295 #ifdef ANDROID_LAYOUT 296 if (obj->isTable()) 297 (static_cast<WebCore::RenderTable *>(obj))->clearSingleColumn(); 298 #endif 299 for (WebCore::RenderObject* n = obj->firstChild(); n; n = n->nextSibling()) 300 recursiveCleanupForFullLayout(n); 301 } 302 303 #if ENABLE(WEB_AUTOFILL) 304 inline string16 getStringFieldAsString16(JNIEnv* env, jobject autoFillProfile, jfieldID fieldId) 305 { 306 jstring str = static_cast<jstring>(env->GetObjectField(autoFillProfile, fieldId)); 307 return str ? jstringToString16(env, str) : string16(); 308 } 309 310 void syncAutoFillProfile(JNIEnv* env, jobject autoFillProfile, WebAutofill* webAutofill) 311 { 312 string16 fullName = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileFullName); 313 string16 emailAddress = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileEmailAddress); 314 string16 companyName = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCompanyName); 315 string16 addressLine1 = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileAddressLine1); 316 string16 addressLine2 = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileAddressLine2); 317 string16 city = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCity); 318 string16 state = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileState); 319 string16 zipCode = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileZipCode); 320 string16 country = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfileCountry); 321 string16 phoneNumber = getStringFieldAsString16(env, autoFillProfile, gFieldIds->mAutoFillProfilePhoneNumber); 322 323 webAutofill->setProfile(fullName, emailAddress, companyName, addressLine1, addressLine2, city, state, zipCode, country, phoneNumber); 324 } 325 #endif 326 327 class WebSettings { 328 public: 329 static void Sync(JNIEnv* env, jobject obj, jint frame) 330 { 331 WebCore::Frame* pFrame = (WebCore::Frame*)frame; 332 ALOG_ASSERT(pFrame, "%s must take a valid frame pointer!", __FUNCTION__); 333 WebCore::Settings* s = pFrame->settings(); 334 if (!s) 335 return; 336 WebCore::CachedResourceLoader* cachedResourceLoader = pFrame->document()->cachedResourceLoader(); 337 338 #ifdef ANDROID_LAYOUT 339 jobject layout = env->GetObjectField(obj, gFieldIds->mLayoutAlgorithm); 340 WebCore::Settings::LayoutAlgorithm l = (WebCore::Settings::LayoutAlgorithm) 341 env->CallIntMethod(layout, gFieldIds->mOrdinal); 342 if (s->layoutAlgorithm() != l) { 343 s->setLayoutAlgorithm(l); 344 if (pFrame->document()) { 345 pFrame->document()->styleSelectorChanged(WebCore::RecalcStyleImmediately); 346 if (pFrame->document()->renderer()) { 347 recursiveCleanupForFullLayout(pFrame->document()->renderer()); 348 ALOG_ASSERT(pFrame->view(), "No view for this frame when trying to relayout"); 349 pFrame->view()->layout(); 350 // FIXME: This call used to scroll the page to put the focus into view. 351 // It worked on the WebViewCore, but now scrolling is done outside of the 352 // WebViewCore, on the UI side, so there needs to be a new way to do this. 353 //pFrame->makeFocusVisible(); 354 } 355 } 356 } 357 #endif 358 jint textSize = env->GetIntField(obj, gFieldIds->mTextSize); 359 float zoomFactor = textSize / 100.0f; 360 if (pFrame->textZoomFactor() != zoomFactor) 361 pFrame->setTextZoomFactor(zoomFactor); 362 363 jstring str = (jstring)env->GetObjectField(obj, gFieldIds->mStandardFontFamily); 364 s->setStandardFontFamily(jstringToWtfString(env, str)); 365 366 str = (jstring)env->GetObjectField(obj, gFieldIds->mFixedFontFamily); 367 s->setFixedFontFamily(jstringToWtfString(env, str)); 368 369 str = (jstring)env->GetObjectField(obj, gFieldIds->mSansSerifFontFamily); 370 s->setSansSerifFontFamily(jstringToWtfString(env, str)); 371 372 str = (jstring)env->GetObjectField(obj, gFieldIds->mSerifFontFamily); 373 s->setSerifFontFamily(jstringToWtfString(env, str)); 374 375 str = (jstring)env->GetObjectField(obj, gFieldIds->mCursiveFontFamily); 376 s->setCursiveFontFamily(jstringToWtfString(env, str)); 377 378 str = (jstring)env->GetObjectField(obj, gFieldIds->mFantasyFontFamily); 379 s->setFantasyFontFamily(jstringToWtfString(env, str)); 380 381 str = (jstring)env->GetObjectField(obj, gFieldIds->mDefaultTextEncoding); 382 s->setDefaultTextEncodingName(jstringToWtfString(env, str)); 383 384 str = (jstring)env->CallObjectMethod(obj, gFieldIds->mGetUserAgentString); 385 WebFrame::getWebFrame(pFrame)->setUserAgent(jstringToWtfString(env, str)); 386 WebViewCore::getWebViewCore(pFrame->view())->setWebRequestContextUserAgent(); 387 388 jint cacheMode = env->GetIntField(obj, gFieldIds->mOverrideCacheMode); 389 WebViewCore::getWebViewCore(pFrame->view())->setWebRequestContextCacheMode(cacheMode); 390 391 str = (jstring)env->CallObjectMethod(obj, gFieldIds->mGetAcceptLanguage); 392 WebRequestContext::setAcceptLanguage(jstringToWtfString(env, str)); 393 394 jint size = env->GetIntField(obj, gFieldIds->mMinimumFontSize); 395 s->setMinimumFontSize(size); 396 397 size = env->GetIntField(obj, gFieldIds->mMinimumLogicalFontSize); 398 s->setMinimumLogicalFontSize(size); 399 400 size = env->GetIntField(obj, gFieldIds->mDefaultFontSize); 401 s->setDefaultFontSize(size); 402 403 size = env->GetIntField(obj, gFieldIds->mDefaultFixedFontSize); 404 s->setDefaultFixedFontSize(size); 405 406 jboolean flag = env->GetBooleanField(obj, gFieldIds->mLoadsImagesAutomatically); 407 s->setLoadsImagesAutomatically(flag); 408 if (flag) 409 cachedResourceLoader->setAutoLoadImages(true); 410 411 #ifdef ANDROID_BLOCK_NETWORK_IMAGE 412 flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkImage); 413 s->setBlockNetworkImage(flag); 414 if(!flag) 415 cachedResourceLoader->setBlockNetworkImage(false); 416 #endif 417 flag = env->GetBooleanField(obj, gFieldIds->mBlockNetworkLoads); 418 WebFrame* webFrame = WebFrame::getWebFrame(pFrame); 419 webFrame->setBlockNetworkLoads(flag); 420 421 flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptEnabled); 422 s->setJavaScriptEnabled(flag); 423 424 flag = env->GetBooleanField(obj, gFieldIds->mAllowUniversalAccessFromFileURLs); 425 s->setAllowUniversalAccessFromFileURLs(flag); 426 427 flag = env->GetBooleanField(obj, gFieldIds->mAllowFileAccessFromFileURLs); 428 s->setAllowFileAccessFromFileURLs(flag); 429 430 // Hyperlink auditing (the ping attribute) has similar privacy 431 // considerations as does the running of JavaScript, so to keep the UI 432 // simpler, we leverage the same setting. 433 s->setHyperlinkAuditingEnabled(flag); 434 435 // ON = 0 436 // ON_DEMAND = 1 437 // OFF = 2 438 jobject pluginState = env->GetObjectField(obj, gFieldIds->mPluginState); 439 int state = env->CallIntMethod(pluginState, gFieldIds->mOrdinal); 440 s->setPluginsEnabled(state < 2); 441 #ifdef ANDROID_PLUGINS 442 s->setPluginsOnDemand(state == 1); 443 #endif 444 445 #if ENABLE(OFFLINE_WEB_APPLICATIONS) 446 // We only enable AppCache if it's been enabled with a call to 447 // setAppCacheEnabled() and if a valid path has been supplied to 448 // setAppCachePath(). Note that the path is applied to all WebViews 449 // whereas enabling is applied per WebView. 450 451 // WebCore asserts that the path is only set once. Since the path is 452 // shared between WebViews, we can't do the required checks to guard 453 // against this in the Java WebSettings. 454 bool isPathValid = false; 455 if (cacheStorage().cacheDirectory().isNull()) { 456 str = static_cast<jstring>(env->GetObjectField(obj, gFieldIds->mAppCachePath)); 457 // Check for non-null string as an optimization, as this is the common case. 458 if (str) { 459 String path = jstringToWtfString(env, str); 460 ALOG_ASSERT(!path.empty(), "Java side should never send empty string for AppCache path"); 461 // This database is created on the first load. If the file 462 // doesn't exist, we create it and set its permissions. The 463 // filename must match that in ApplicationCacheStorage.cpp. 464 String filename = pathByAppendingComponent(path, "ApplicationCache.db"); 465 int fd = open(filename.utf8().data(), O_CREAT, permissionFlags660); 466 if (fd >= 0) { 467 close(fd); 468 cacheStorage().setCacheDirectory(path); 469 isPathValid = true; 470 } 471 } 472 } else 473 isPathValid = true; 474 475 flag = env->GetBooleanField(obj, gFieldIds->mAppCacheEnabled); 476 s->setOfflineWebApplicationCacheEnabled(flag && isPathValid); 477 478 jlong maxsize = env->GetLongField(obj, gFieldIds->mAppCacheMaxSize); 479 cacheStorage().setMaximumSize(maxsize); 480 #endif 481 482 flag = env->GetBooleanField(obj, gFieldIds->mJavaScriptCanOpenWindowsAutomatically); 483 s->setJavaScriptCanOpenWindowsAutomatically(flag); 484 485 #ifdef ANDROID_LAYOUT 486 flag = env->GetBooleanField(obj, gFieldIds->mUseWideViewport); 487 s->setUseWideViewport(flag); 488 #endif 489 490 #ifdef ANDROID_MULTIPLE_WINDOWS 491 flag = env->GetBooleanField(obj, gFieldIds->mSupportMultipleWindows); 492 s->setSupportMultipleWindows(flag); 493 #endif 494 flag = env->GetBooleanField(obj, gFieldIds->mShrinksStandaloneImagesToFit); 495 s->setShrinksStandaloneImagesToFit(flag); 496 jlong maxImage = env->GetLongField(obj, gFieldIds->mMaximumDecodedImageSize); 497 // Since in ImageSourceAndroid.cpp, the image will always not exceed 498 // MAX_SIZE_BEFORE_SUBSAMPLE, there's no need to pass the max value to 499 // WebCore, which checks (image_width * image_height * 4) as an 500 // estimation against the max value, which is done in CachedImage.cpp. 501 // And there're cases where the decoded image size will not 502 // exceed the max, but the WebCore estimation will. So the following 503 // code is commented out to fix those cases. 504 // if (maxImage == 0) 505 // maxImage = computeMaxBitmapSizeForCache(); 506 s->setMaximumDecodedImageSize(maxImage); 507 508 flag = env->GetBooleanField(obj, gFieldIds->mPrivateBrowsingEnabled); 509 s->setPrivateBrowsingEnabled(flag); 510 511 flag = env->GetBooleanField(obj, gFieldIds->mSyntheticLinksEnabled); 512 s->setDefaultFormatDetection(flag); 513 s->setFormatDetectionAddress(flag); 514 s->setFormatDetectionEmail(flag); 515 s->setFormatDetectionTelephone(flag); 516 #if ENABLE(DATABASE) 517 flag = env->GetBooleanField(obj, gFieldIds->mDatabaseEnabled); 518 WebCore::Database::setIsAvailable(flag); 519 520 flag = env->GetBooleanField(obj, gFieldIds->mDatabasePathHasBeenSet); 521 if (flag) { 522 // If the user has set the database path, sync it to the DatabaseTracker. 523 str = (jstring)env->GetObjectField(obj, gFieldIds->mDatabasePath); 524 if (str) { 525 String path = jstringToWtfString(env, str); 526 DatabaseTracker::tracker().setDatabaseDirectoryPath(path); 527 // This database is created when the first HTML5 Database object is 528 // instantiated. If the file doesn't exist, we create it and set its 529 // permissions. The filename must match that in 530 // DatabaseTracker.cpp. 531 String filename = SQLiteFileSystem::appendDatabaseFileNameToPath(path, "Databases.db"); 532 int fd = open(filename.utf8().data(), O_CREAT | O_EXCL, permissionFlags660); 533 if (fd >= 0) 534 close(fd); 535 } 536 } 537 #endif 538 #if ENABLE(DOM_STORAGE) 539 flag = env->GetBooleanField(obj, gFieldIds->mDomStorageEnabled); 540 s->setLocalStorageEnabled(flag); 541 str = (jstring)env->GetObjectField(obj, gFieldIds->mDatabasePath); 542 if (str) { 543 WTF::String localStorageDatabasePath = jstringToWtfString(env,str); 544 if (localStorageDatabasePath.length()) { 545 localStorageDatabasePath = WebCore::pathByAppendingComponent( 546 localStorageDatabasePath, "localstorage"); 547 // We need 770 for folders 548 mkdir(localStorageDatabasePath.utf8().data(), 549 permissionFlags660 | S_IXUSR | S_IXGRP); 550 s->setLocalStorageDatabasePath(localStorageDatabasePath); 551 } 552 } 553 #endif 554 555 flag = env->GetBooleanField(obj, gFieldIds->mGeolocationEnabled); 556 GeolocationPermissions::setAlwaysDeny(!flag); 557 str = (jstring)env->GetObjectField(obj, gFieldIds->mGeolocationDatabasePath); 558 if (str) { 559 String path = jstringToWtfString(env, str); 560 GeolocationPermissions::setDatabasePath(path); 561 GeolocationPositionCache::instance()->setDatabasePath(path); 562 // This database is created when the first Geolocation object is 563 // instantiated. If the file doesn't exist, we create it and set its 564 // permissions. The filename must match that in 565 // GeolocationPositionCache.cpp. 566 String filename = SQLiteFileSystem::appendDatabaseFileNameToPath(path, "CachedGeoposition.db"); 567 int fd = open(filename.utf8().data(), O_CREAT | O_EXCL, permissionFlags660); 568 if (fd >= 0) 569 close(fd); 570 } 571 572 flag = env->GetBooleanField(obj, gFieldIds->mXSSAuditorEnabled); 573 s->setXSSAuditorEnabled(flag); 574 575 #if ENABLE(LINK_PREFETCH) 576 flag = env->GetBooleanField(obj, gFieldIds->mLinkPrefetchEnabled); 577 s->setLinkPrefetchEnabled(flag); 578 #endif 579 580 size = env->GetIntField(obj, gFieldIds->mPageCacheCapacity); 581 if (size > 0) { 582 s->setUsesPageCache(true); 583 WebCore::pageCache()->setCapacity(size); 584 } else 585 s->setUsesPageCache(false); 586 587 #if ENABLE(WEB_AUTOFILL) 588 flag = env->GetBooleanField(obj, gFieldIds->mAutoFillEnabled); 589 // TODO: This updates the Settings WebCore side with the user's 590 // preference for autofill and will stop WebCore making requests 591 // into the chromium autofill code. That code in Chromium also has 592 // a notion of being enabled/disabled that gets read from the users 593 // preferences. At the moment, it's hardcoded to true on Android 594 // (see chrome/browser/autofill/autofill_manager.cc:405). This 595 // setting should probably be synced into Chromium also. 596 597 s->setAutoFillEnabled(flag); 598 599 if (flag) { 600 EditorClientAndroid* editorC = static_cast<EditorClientAndroid*>(pFrame->page()->editorClient()); 601 WebAutofill* webAutofill = editorC->getAutofill(); 602 // Set the active AutofillProfile data. 603 jobject autoFillProfile = env->GetObjectField(obj, gFieldIds->mAutoFillProfile); 604 if (autoFillProfile) 605 syncAutoFillProfile(env, autoFillProfile, webAutofill); 606 else { 607 // The autofill profile is null. We need to tell Chromium about this because 608 // this may be because the user just deleted their profile but left the 609 // autofill feature setting enabled. 610 webAutofill->clearProfiles(); 611 } 612 } 613 #endif 614 615 // This is required to enable the XMLTreeViewer when loading an XML document that 616 // has no style attached to it. http://trac.webkit.org/changeset/79799 617 s->setDeveloperExtrasEnabled(true); 618 s->setSpatialNavigationEnabled(true); 619 bool echoPassword = env->GetBooleanField(obj, 620 gFieldIds->mPasswordEchoEnabled); 621 s->setPasswordEchoEnabled(echoPassword); 622 623 flag = env->GetBooleanField(obj, gFieldIds->mMediaPlaybackRequiresUserGesture); 624 s->setMediaPlaybackRequiresUserGesture(flag); 625 } 626 }; 627 628 629 //------------------------------------------------------------- 630 // JNI registration 631 //------------------------------------------------------------- 632 633 static JNINativeMethod gWebSettingsMethods[] = { 634 { "nativeSync", "(I)V", 635 (void*) WebSettings::Sync } 636 }; 637 638 int registerWebSettings(JNIEnv* env) 639 { 640 jclass clazz = env->FindClass("android/webkit/WebSettingsClassic"); 641 ALOG_ASSERT(clazz, "Unable to find class WebSettingsClassic!"); 642 gFieldIds = new FieldIds(env, clazz); 643 env->DeleteLocalRef(clazz); 644 return jniRegisterNativeMethods(env, "android/webkit/WebSettingsClassic", 645 gWebSettingsMethods, NELEM(gWebSettingsMethods)); 646 } 647 648 } 649