• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
FieldIdsandroid::FieldIds65     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
recursiveCleanupForFullLayout(WebCore::RenderObject * obj)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)
getStringFieldAsString16(JNIEnv * env,jobject autoFillProfile,jfieldID fieldId)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 
syncAutoFillProfile(JNIEnv * env,jobject autoFillProfile,WebAutofill * webAutofill)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:
Sync(JNIEnv * env,jobject obj,jint frame)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 
registerWebSettings(JNIEnv * env)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