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