OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "android_webview/native/aw_settings.h" | |
6 | |
7 #include "android_webview/browser/aw_content_browser_client.h" | |
8 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h" | |
9 #include "android_webview/common/aw_content_client.h" | |
10 #include "android_webview/native/aw_contents.h" | |
11 #include "base/android/jni_android.h" | |
12 #include "base/android/jni_string.h" | |
13 #include "base/macros.h" | |
14 #include "base/memory/ptr_util.h" | |
15 #include "base/supports_user_data.h" | |
16 #include "content/public/browser/navigation_controller.h" | |
17 #include "content/public/browser/navigation_entry.h" | |
18 #include "content/public/browser/render_view_host.h" | |
19 #include "content/public/browser/web_contents.h" | |
20 #include "content/public/common/renderer_preferences.h" | |
21 #include "content/public/common/web_preferences.h" | |
22 #include "jni/AwSettings_jni.h" | |
23 #include "ui/gfx/font_render_params.h" | |
24 | |
25 using base::android::ConvertJavaStringToUTF16; | |
26 using base::android::ConvertUTF8ToJavaString; | |
27 using base::android::JavaParamRef; | |
28 using base::android::ScopedJavaLocalRef; | |
29 using content::RendererPreferences; | |
30 using content::WebPreferences; | |
31 | |
32 namespace android_webview { | |
33 | |
34 namespace { | |
35 | |
36 void PopulateFixedRendererPreferences(RendererPreferences* prefs) { | |
37 prefs->tap_multiple_targets_strategy = | |
38 content::TAP_MULTIPLE_TARGETS_STRATEGY_NONE; | |
39 | |
40 // TODO(boliu): Deduplicate with chrome/ code. | |
41 CR_DEFINE_STATIC_LOCAL(const gfx::FontRenderParams, params, | |
42 (gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), NULL))); | |
43 prefs->should_antialias_text = params.antialiasing; | |
44 prefs->use_subpixel_positioning = params.subpixel_positioning; | |
45 prefs->hinting = params.hinting; | |
46 prefs->use_autohinter = params.autohinter; | |
47 prefs->use_bitmaps = params.use_bitmaps; | |
48 prefs->subpixel_rendering = params.subpixel_rendering; | |
49 } | |
50 | |
51 void PopulateFixedWebPreferences(WebPreferences* web_prefs) { | |
52 web_prefs->shrinks_standalone_images_to_fit = false; | |
53 web_prefs->should_clear_document_background = false; | |
54 web_prefs->viewport_meta_enabled = true; | |
55 } | |
56 | |
57 const void* const kAwSettingsUserDataKey = &kAwSettingsUserDataKey; | |
58 | |
59 }; // namespace | |
60 | |
61 class AwSettingsUserData : public base::SupportsUserData::Data { | |
62 public: | |
63 explicit AwSettingsUserData(AwSettings* ptr) : settings_(ptr) {} | |
64 | |
65 static AwSettings* GetSettings(content::WebContents* web_contents) { | |
66 if (!web_contents) | |
67 return NULL; | |
68 AwSettingsUserData* data = static_cast<AwSettingsUserData*>( | |
69 web_contents->GetUserData(kAwSettingsUserDataKey)); | |
70 return data ? data->settings_ : NULL; | |
71 } | |
72 | |
73 private: | |
74 AwSettings* settings_; | |
75 }; | |
76 | |
77 AwSettings::AwSettings(JNIEnv* env, | |
78 jobject obj, | |
79 content::WebContents* web_contents) | |
80 : WebContentsObserver(web_contents), | |
81 renderer_prefs_initialized_(false), | |
82 aw_settings_(env, obj) { | |
83 web_contents->SetUserData(kAwSettingsUserDataKey, | |
84 base::MakeUnique<AwSettingsUserData>(this)); | |
85 } | |
86 | |
87 AwSettings::~AwSettings() { | |
88 if (web_contents()) { | |
89 web_contents()->SetUserData(kAwSettingsUserDataKey, NULL); | |
90 } | |
91 | |
92 JNIEnv* env = base::android::AttachCurrentThread(); | |
93 ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env); | |
94 if (scoped_obj.is_null()) | |
95 return; | |
96 Java_AwSettings_nativeAwSettingsGone(env, scoped_obj, | |
97 reinterpret_cast<intptr_t>(this)); | |
98 } | |
99 | |
100 void AwSettings::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { | |
101 delete this; | |
102 } | |
103 | |
104 AwSettings* AwSettings::FromWebContents(content::WebContents* web_contents) { | |
105 return AwSettingsUserData::GetSettings(web_contents); | |
106 } | |
107 | |
108 AwRenderViewHostExt* AwSettings::GetAwRenderViewHostExt() { | |
109 if (!web_contents()) return NULL; | |
110 AwContents* contents = AwContents::FromWebContents(web_contents()); | |
111 if (!contents) return NULL; | |
112 return contents->render_view_host_ext(); | |
113 } | |
114 | |
115 void AwSettings::ResetScrollAndScaleState(JNIEnv* env, | |
116 const JavaParamRef<jobject>& obj) { | |
117 AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt(); | |
118 if (!rvhe) return; | |
119 rvhe->ResetScrollAndScaleState(); | |
120 } | |
121 | |
122 void AwSettings::UpdateEverything() { | |
123 JNIEnv* env = base::android::AttachCurrentThread(); | |
124 CHECK(env); | |
125 ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env); | |
126 if (scoped_obj.is_null()) | |
127 return; | |
128 // Grab the lock and call UpdateEverythingLocked. | |
129 Java_AwSettings_updateEverything(env, scoped_obj); | |
130 } | |
131 | |
132 void AwSettings::UpdateEverythingLocked(JNIEnv* env, | |
133 const JavaParamRef<jobject>& obj) { | |
134 UpdateInitialPageScaleLocked(env, obj); | |
135 UpdateWebkitPreferencesLocked(env, obj); | |
136 UpdateUserAgentLocked(env, obj); | |
137 ResetScrollAndScaleState(env, obj); | |
138 UpdateFormDataPreferencesLocked(env, obj); | |
139 UpdateRendererPreferencesLocked(env, obj); | |
140 UpdateOffscreenPreRasterLocked(env, obj); | |
141 } | |
142 | |
143 void AwSettings::UpdateUserAgentLocked(JNIEnv* env, | |
144 const JavaParamRef<jobject>& obj) { | |
145 if (!web_contents()) return; | |
146 | |
147 ScopedJavaLocalRef<jstring> str = | |
148 Java_AwSettings_getUserAgentLocked(env, obj); | |
149 bool ua_overidden = str.obj() != NULL; | |
150 | |
151 if (ua_overidden) { | |
152 std::string override = base::android::ConvertJavaStringToUTF8(str); | |
153 web_contents()->SetUserAgentOverride(override); | |
154 } | |
155 | |
156 const content::NavigationController& controller = | |
157 web_contents()->GetController(); | |
158 for (int i = 0; i < controller.GetEntryCount(); ++i) | |
159 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(ua_overidden); | |
160 } | |
161 | |
162 void AwSettings::UpdateWebkitPreferencesLocked( | |
163 JNIEnv* env, | |
164 const JavaParamRef<jobject>& obj) { | |
165 if (!web_contents()) return; | |
166 AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt(); | |
167 if (!render_view_host_ext) return; | |
168 | |
169 content::RenderViewHost* render_view_host = | |
170 web_contents()->GetRenderViewHost(); | |
171 if (!render_view_host) return; | |
172 render_view_host->OnWebkitPreferencesChanged(); | |
173 } | |
174 | |
175 void AwSettings::UpdateInitialPageScaleLocked( | |
176 JNIEnv* env, | |
177 const JavaParamRef<jobject>& obj) { | |
178 AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt(); | |
179 if (!rvhe) return; | |
180 | |
181 float initial_page_scale_percent = | |
182 Java_AwSettings_getInitialPageScalePercentLocked(env, obj); | |
183 if (initial_page_scale_percent == 0) { | |
184 rvhe->SetInitialPageScale(-1); | |
185 } else { | |
186 float dip_scale = static_cast<float>( | |
187 Java_AwSettings_getDIPScaleLocked(env, obj)); | |
188 rvhe->SetInitialPageScale(initial_page_scale_percent / dip_scale / 100.0f); | |
189 } | |
190 } | |
191 | |
192 void AwSettings::UpdateFormDataPreferencesLocked( | |
193 JNIEnv* env, | |
194 const JavaParamRef<jobject>& obj) { | |
195 if (!web_contents()) return; | |
196 AwContents* contents = AwContents::FromWebContents(web_contents()); | |
197 if (!contents) return; | |
198 | |
199 contents->SetSaveFormData(Java_AwSettings_getSaveFormDataLocked(env, obj)); | |
200 } | |
201 | |
202 void AwSettings::UpdateRendererPreferencesLocked( | |
203 JNIEnv* env, | |
204 const JavaParamRef<jobject>& obj) { | |
205 if (!web_contents()) return; | |
206 | |
207 bool update_prefs = false; | |
208 RendererPreferences* prefs = web_contents()->GetMutableRendererPrefs(); | |
209 | |
210 if (!renderer_prefs_initialized_) { | |
211 PopulateFixedRendererPreferences(prefs); | |
212 renderer_prefs_initialized_ = true; | |
213 update_prefs = true; | |
214 } | |
215 | |
216 if (prefs->accept_languages.compare( | |
217 AwContentBrowserClient::GetAcceptLangsImpl())) { | |
218 prefs->accept_languages = AwContentBrowserClient::GetAcceptLangsImpl(); | |
219 update_prefs = true; | |
220 } | |
221 | |
222 content::RenderViewHost* host = web_contents()->GetRenderViewHost(); | |
223 if (update_prefs && host) | |
224 host->SyncRendererPrefs(); | |
225 } | |
226 | |
227 void AwSettings::UpdateOffscreenPreRasterLocked( | |
228 JNIEnv* env, | |
229 const JavaParamRef<jobject>& obj) { | |
230 AwContents* contents = AwContents::FromWebContents(web_contents()); | |
231 if (contents) { | |
232 contents->SetOffscreenPreRaster( | |
233 Java_AwSettings_getOffscreenPreRasterLocked(env, obj)); | |
234 } | |
235 } | |
236 | |
237 void AwSettings::RenderViewHostChanged(content::RenderViewHost* old_host, | |
238 content::RenderViewHost* new_host) { | |
239 DCHECK_EQ(new_host, web_contents()->GetRenderViewHost()); | |
240 | |
241 UpdateEverything(); | |
242 } | |
243 | |
244 void AwSettings::WebContentsDestroyed() { | |
245 delete this; | |
246 } | |
247 | |
248 void AwSettings::PopulateWebPreferences(WebPreferences* web_prefs) { | |
249 JNIEnv* env = base::android::AttachCurrentThread(); | |
250 CHECK(env); | |
251 ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env); | |
252 if (scoped_obj.is_null()) | |
253 return; | |
254 // Grab the lock and call PopulateWebPreferencesLocked. | |
255 Java_AwSettings_populateWebPreferences(env, scoped_obj, | |
256 reinterpret_cast<jlong>(web_prefs)); | |
257 } | |
258 | |
259 void AwSettings::PopulateWebPreferencesLocked(JNIEnv* env, | |
260 const JavaParamRef<jobject>& obj, | |
261 jlong web_prefs_ptr) { | |
262 AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt(); | |
263 if (!render_view_host_ext) return; | |
264 | |
265 WebPreferences* web_prefs = reinterpret_cast<WebPreferences*>(web_prefs_ptr); | |
266 PopulateFixedWebPreferences(web_prefs); | |
267 | |
268 web_prefs->text_autosizing_enabled = | |
269 Java_AwSettings_getTextAutosizingEnabledLocked(env, obj); | |
270 | |
271 int text_size_percent = Java_AwSettings_getTextSizePercentLocked(env, obj); | |
272 if (web_prefs->text_autosizing_enabled) { | |
273 web_prefs->font_scale_factor = text_size_percent / 100.0f; | |
274 web_prefs->force_enable_zoom = text_size_percent >= 130; | |
275 // Use the default zoom factor value when Text Autosizer is turned on. | |
276 render_view_host_ext->SetTextZoomFactor(1); | |
277 } else { | |
278 web_prefs->force_enable_zoom = false; | |
279 render_view_host_ext->SetTextZoomFactor(text_size_percent / 100.0f); | |
280 } | |
281 | |
282 web_prefs->standard_font_family_map[content::kCommonScript] = | |
283 ConvertJavaStringToUTF16( | |
284 Java_AwSettings_getStandardFontFamilyLocked(env, obj)); | |
285 | |
286 web_prefs->fixed_font_family_map[content::kCommonScript] = | |
287 ConvertJavaStringToUTF16( | |
288 Java_AwSettings_getFixedFontFamilyLocked(env, obj)); | |
289 | |
290 web_prefs->sans_serif_font_family_map[content::kCommonScript] = | |
291 ConvertJavaStringToUTF16( | |
292 Java_AwSettings_getSansSerifFontFamilyLocked(env, obj)); | |
293 | |
294 web_prefs->serif_font_family_map[content::kCommonScript] = | |
295 ConvertJavaStringToUTF16( | |
296 Java_AwSettings_getSerifFontFamilyLocked(env, obj)); | |
297 | |
298 web_prefs->cursive_font_family_map[content::kCommonScript] = | |
299 ConvertJavaStringToUTF16( | |
300 Java_AwSettings_getCursiveFontFamilyLocked(env, obj)); | |
301 | |
302 web_prefs->fantasy_font_family_map[content::kCommonScript] = | |
303 ConvertJavaStringToUTF16( | |
304 Java_AwSettings_getFantasyFontFamilyLocked(env, obj)); | |
305 | |
306 web_prefs->default_encoding = ConvertJavaStringToUTF8( | |
307 Java_AwSettings_getDefaultTextEncodingLocked(env, obj)); | |
308 | |
309 web_prefs->minimum_font_size = | |
310 Java_AwSettings_getMinimumFontSizeLocked(env, obj); | |
311 | |
312 web_prefs->minimum_logical_font_size = | |
313 Java_AwSettings_getMinimumLogicalFontSizeLocked(env, obj); | |
314 | |
315 web_prefs->default_font_size = | |
316 Java_AwSettings_getDefaultFontSizeLocked(env, obj); | |
317 | |
318 web_prefs->default_fixed_font_size = | |
319 Java_AwSettings_getDefaultFixedFontSizeLocked(env, obj); | |
320 | |
321 // Blink's LoadsImagesAutomatically and ImagesEnabled must be | |
322 // set cris-cross to Android's. See | |
323 // https://code.google.com/p/chromium/issues/detail?id=224317#c26 | |
324 web_prefs->loads_images_automatically = | |
325 Java_AwSettings_getImagesEnabledLocked(env, obj); | |
326 web_prefs->images_enabled = | |
327 Java_AwSettings_getLoadsImagesAutomaticallyLocked(env, obj); | |
328 | |
329 web_prefs->javascript_enabled = | |
330 Java_AwSettings_getJavaScriptEnabledLocked(env, obj); | |
331 | |
332 web_prefs->allow_universal_access_from_file_urls = | |
333 Java_AwSettings_getAllowUniversalAccessFromFileURLsLocked(env, obj); | |
334 | |
335 web_prefs->allow_file_access_from_file_urls = | |
336 Java_AwSettings_getAllowFileAccessFromFileURLsLocked(env, obj); | |
337 | |
338 web_prefs->javascript_can_open_windows_automatically = | |
339 Java_AwSettings_getJavaScriptCanOpenWindowsAutomaticallyLocked(env, obj); | |
340 | |
341 web_prefs->supports_multiple_windows = | |
342 Java_AwSettings_getSupportMultipleWindowsLocked(env, obj); | |
343 | |
344 web_prefs->plugins_enabled = | |
345 !Java_AwSettings_getPluginsDisabledLocked(env, obj); | |
346 | |
347 web_prefs->application_cache_enabled = | |
348 Java_AwSettings_getAppCacheEnabledLocked(env, obj); | |
349 | |
350 web_prefs->local_storage_enabled = | |
351 Java_AwSettings_getDomStorageEnabledLocked(env, obj); | |
352 | |
353 web_prefs->databases_enabled = | |
354 Java_AwSettings_getDatabaseEnabledLocked(env, obj); | |
355 | |
356 web_prefs->wide_viewport_quirk = true; | |
357 web_prefs->use_wide_viewport = | |
358 Java_AwSettings_getUseWideViewportLocked(env, obj); | |
359 | |
360 web_prefs->force_zero_layout_height = | |
361 Java_AwSettings_getForceZeroLayoutHeightLocked(env, obj); | |
362 | |
363 const bool zero_layout_height_disables_viewport_quirk = | |
364 Java_AwSettings_getZeroLayoutHeightDisablesViewportQuirkLocked(env, obj); | |
365 web_prefs->viewport_enabled = !(zero_layout_height_disables_viewport_quirk && | |
366 web_prefs->force_zero_layout_height); | |
367 | |
368 web_prefs->double_tap_to_zoom_enabled = | |
369 Java_AwSettings_supportsDoubleTapZoomLocked(env, obj); | |
370 | |
371 web_prefs->initialize_at_minimum_page_scale = | |
372 Java_AwSettings_getLoadWithOverviewModeLocked(env, obj); | |
373 | |
374 web_prefs->user_gesture_required_for_media_playback = | |
375 Java_AwSettings_getMediaPlaybackRequiresUserGestureLocked(env, obj); | |
376 | |
377 ScopedJavaLocalRef<jstring> url = | |
378 Java_AwSettings_getDefaultVideoPosterURLLocked(env, obj); | |
379 web_prefs->default_video_poster_url = url.obj() ? | |
380 GURL(ConvertJavaStringToUTF8(url)) : GURL(); | |
381 | |
382 bool support_quirks = Java_AwSettings_getSupportLegacyQuirksLocked(env, obj); | |
383 // Please see the corresponding Blink settings for bug references. | |
384 web_prefs->support_deprecated_target_density_dpi = support_quirks; | |
385 web_prefs->use_legacy_background_size_shorthand_behavior = support_quirks; | |
386 web_prefs->viewport_meta_layout_size_quirk = support_quirks; | |
387 web_prefs->viewport_meta_merge_content_quirk = support_quirks; | |
388 web_prefs->viewport_meta_non_user_scalable_quirk = support_quirks; | |
389 web_prefs->viewport_meta_zero_values_quirk = support_quirks; | |
390 web_prefs->clobber_user_agent_initial_scale_quirk = support_quirks; | |
391 web_prefs->ignore_main_frame_overflow_hidden_quirk = support_quirks; | |
392 web_prefs->report_screen_size_in_physical_pixels_quirk = support_quirks; | |
393 | |
394 web_prefs->resue_global_for_unowned_main_frame = | |
395 Java_AwSettings_getAllowEmptyDocumentPersistenceLocked(env, obj); | |
396 | |
397 web_prefs->password_echo_enabled = | |
398 Java_AwSettings_getPasswordEchoEnabledLocked(env, obj); | |
399 web_prefs->spatial_navigation_enabled = | |
400 Java_AwSettings_getSpatialNavigationLocked(env, obj); | |
401 | |
402 bool enable_supported_hardware_accelerated_features = | |
403 Java_AwSettings_getEnableSupportedHardwareAcceleratedFeaturesLocked( | |
404 env, obj); | |
405 | |
406 bool accelerated_2d_canvas_enabled_by_switch = | |
407 web_prefs->accelerated_2d_canvas_enabled; | |
408 web_prefs->accelerated_2d_canvas_enabled = true; | |
409 if (!accelerated_2d_canvas_enabled_by_switch || | |
410 !enable_supported_hardware_accelerated_features) { | |
411 // Any canvas smaller than this will fallback to software. Abusing this | |
412 // slightly to turn canvas off without changing | |
413 // accelerated_2d_canvas_enabled, which also affects compositing mode. | |
414 // Using 100M instead of max int to avoid overflows. | |
415 web_prefs->minimum_accelerated_2d_canvas_size = 100 * 1000 * 1000; | |
416 } | |
417 web_prefs->experimental_webgl_enabled = | |
418 web_prefs->experimental_webgl_enabled && | |
419 enable_supported_hardware_accelerated_features; | |
420 | |
421 // If strict mixed content checking is enabled then running should not be | |
422 // allowed. | |
423 DCHECK(!Java_AwSettings_getUseStricMixedContentCheckingLocked(env, obj) || | |
424 !Java_AwSettings_getAllowRunningInsecureContentLocked(env, obj)); | |
425 web_prefs->allow_running_insecure_content = | |
426 Java_AwSettings_getAllowRunningInsecureContentLocked(env, obj); | |
427 web_prefs->strict_mixed_content_checking = | |
428 Java_AwSettings_getUseStricMixedContentCheckingLocked(env, obj); | |
429 | |
430 web_prefs->fullscreen_supported = | |
431 Java_AwSettings_getFullscreenSupportedLocked(env, obj); | |
432 web_prefs->record_whole_document = | |
433 Java_AwSettings_getRecordFullDocument(env, obj); | |
434 | |
435 // TODO(jww): This should be removed once sufficient warning has been given of | |
436 // possible API breakage because of disabling insecure use of geolocation. | |
437 web_prefs->allow_geolocation_on_insecure_origins = | |
438 Java_AwSettings_getAllowGeolocationOnInsecureOrigins(env, obj); | |
439 | |
440 web_prefs->do_not_update_selection_on_mutating_selection_range = | |
441 Java_AwSettings_getDoNotUpdateSelectionOnMutatingSelectionRange(env, obj); | |
442 | |
443 // Keep spellcheck disabled on html elements unless the spellcheck="true" | |
444 // attribute is explicitly specified. This "opt-in" behavior is for backward | |
445 // consistency in apps that use WebView (see crbug.com/652314). | |
446 web_prefs->spellcheck_enabled_by_default = false; | |
447 } | |
448 | |
449 static jlong Init(JNIEnv* env, | |
450 const JavaParamRef<jobject>& obj, | |
451 const JavaParamRef<jobject>& web_contents) { | |
452 content::WebContents* contents = content::WebContents::FromJavaWebContents( | |
453 web_contents); | |
454 AwSettings* settings = new AwSettings(env, obj, contents); | |
455 return reinterpret_cast<intptr_t>(settings); | |
456 } | |
457 | |
458 static ScopedJavaLocalRef<jstring> GetDefaultUserAgent( | |
459 JNIEnv* env, | |
460 const JavaParamRef<jclass>& clazz) { | |
461 return base::android::ConvertUTF8ToJavaString(env, GetUserAgent()); | |
462 } | |
463 | |
464 bool RegisterAwSettings(JNIEnv* env) { | |
465 return RegisterNativesImpl(env); | |
466 } | |
467 | |
468 } // namespace android_webview | |
OLD | NEW |