Home | History | Annotate | Download | only in jni
      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