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         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