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.
5 #include "android_webview/native/aw_settings.h"
7 #include "android_webview/browser/renderer_host/aw_render_view_host_ext.h"
8 #include "android_webview/common/aw_content_client.h"
9 #include "android_webview/native/aw_contents.h"
10 #include "base/android/jni_android.h"
11 #include "base/android/jni_string.h"
12 #include "base/command_line.h"
13 #include "base/supports_user_data.h"
14 #include "content/public/browser/navigation_controller.h"
15 #include "content/public/browser/navigation_entry.h"
16 #include "content/public/browser/render_view_host.h"
17 #include "content/public/browser/web_contents.h"
18 #include "content/public/common/content_switches.h"
19 #include "jni/AwSettings_jni.h"
20 #include "webkit/common/webpreferences.h"
22 using base::android::ConvertJavaStringToUTF16
;
23 using base::android::ConvertUTF8ToJavaString
;
24 using base::android::ScopedJavaLocalRef
;
26 namespace android_webview
{
28 const void* kAwSettingsUserDataKey
= &kAwSettingsUserDataKey
;
30 class AwSettingsUserData
: public base::SupportsUserData::Data
{
32 AwSettingsUserData(AwSettings
* ptr
) : settings_(ptr
) {}
34 static AwSettings
* GetSettings(content::WebContents
* web_contents
) {
37 AwSettingsUserData
* data
= reinterpret_cast<AwSettingsUserData
*>(
38 web_contents
->GetUserData(kAwSettingsUserDataKey
));
39 return data
? data
->settings_
: NULL
;
43 AwSettings
* settings_
;
46 AwSettings::AwSettings(JNIEnv
* env
, jobject obj
, jlong web_contents
)
47 : WebContentsObserver(
48 reinterpret_cast<content::WebContents
*>(web_contents
)),
49 accelerated_2d_canvas_disabled_by_switch_(
50 CommandLine::ForCurrentProcess()->HasSwitch(
51 switches::kDisableAccelerated2dCanvas
)),
52 aw_settings_(env
, obj
) {
53 reinterpret_cast<content::WebContents
*>(web_contents
)->
54 SetUserData(kAwSettingsUserDataKey
, new AwSettingsUserData(this));
57 AwSettings::~AwSettings() {
59 web_contents()->SetUserData(kAwSettingsUserDataKey
, NULL
);
62 JNIEnv
* env
= base::android::AttachCurrentThread();
63 ScopedJavaLocalRef
<jobject
> scoped_obj
= aw_settings_
.get(env
);
64 jobject obj
= scoped_obj
.obj();
66 Java_AwSettings_nativeAwSettingsGone(env
, obj
,
67 reinterpret_cast<intptr_t>(this));
70 void AwSettings::Destroy(JNIEnv
* env
, jobject obj
) {
74 AwSettings
* AwSettings::FromWebContents(content::WebContents
* web_contents
) {
75 return AwSettingsUserData::GetSettings(web_contents
);
78 AwRenderViewHostExt
* AwSettings::GetAwRenderViewHostExt() {
79 if (!web_contents()) return NULL
;
80 AwContents
* contents
= AwContents::FromWebContents(web_contents());
81 if (!contents
) return NULL
;
82 return contents
->render_view_host_ext();
85 void AwSettings::ResetScrollAndScaleState(JNIEnv
* env
, jobject obj
) {
86 AwRenderViewHostExt
* rvhe
= GetAwRenderViewHostExt();
88 rvhe
->ResetScrollAndScaleState();
91 void AwSettings::UpdateEverything() {
92 JNIEnv
* env
= base::android::AttachCurrentThread();
94 ScopedJavaLocalRef
<jobject
> scoped_obj
= aw_settings_
.get(env
);
95 jobject obj
= scoped_obj
.obj();
97 // Grab the lock and call UpdateEverythingLocked.
98 Java_AwSettings_updateEverything(env
, obj
);
101 void AwSettings::UpdateEverythingLocked(JNIEnv
* env
, jobject obj
) {
102 UpdateInitialPageScaleLocked(env
, obj
);
103 UpdateWebkitPreferencesLocked(env
, obj
);
104 UpdateUserAgentLocked(env
, obj
);
105 ResetScrollAndScaleState(env
, obj
);
106 UpdateFormDataPreferencesLocked(env
, obj
);
109 void AwSettings::UpdateUserAgentLocked(JNIEnv
* env
, jobject obj
) {
110 if (!web_contents()) return;
112 ScopedJavaLocalRef
<jstring
> str
=
113 Java_AwSettings_getUserAgentLocked(env
, obj
);
114 bool ua_overidden
= str
.obj() != NULL
;
117 std::string override
= base::android::ConvertJavaStringToUTF8(str
);
118 web_contents()->SetUserAgentOverride(override
);
121 const content::NavigationController
& controller
=
122 web_contents()->GetController();
123 for (int i
= 0; i
< controller
.GetEntryCount(); ++i
)
124 controller
.GetEntryAtIndex(i
)->SetIsOverridingUserAgent(ua_overidden
);
127 void AwSettings::UpdateWebkitPreferencesLocked(JNIEnv
* env
, jobject obj
) {
128 if (!web_contents()) return;
129 AwRenderViewHostExt
* render_view_host_ext
= GetAwRenderViewHostExt();
130 if (!render_view_host_ext
) return;
132 content::RenderViewHost
* render_view_host
=
133 web_contents()->GetRenderViewHost();
134 if (!render_view_host
) return;
135 render_view_host
->UpdateWebkitPreferences(
136 render_view_host
->GetWebkitPreferences());
139 void AwSettings::UpdateInitialPageScaleLocked(JNIEnv
* env
, jobject obj
) {
140 AwRenderViewHostExt
* rvhe
= GetAwRenderViewHostExt();
143 float initial_page_scale_percent
=
144 Java_AwSettings_getInitialPageScalePercentLocked(env
, obj
);
145 if (initial_page_scale_percent
== 0) {
146 rvhe
->SetInitialPageScale(-1);
148 float dip_scale
= static_cast<float>(
149 Java_AwSettings_getDIPScaleLocked(env
, obj
));
150 rvhe
->SetInitialPageScale(initial_page_scale_percent
/ dip_scale
/ 100.0f
);
154 void AwSettings::UpdateFormDataPreferencesLocked(JNIEnv
* env
, jobject obj
) {
155 if (!web_contents()) return;
156 AwContents
* contents
= AwContents::FromWebContents(web_contents());
157 if (!contents
) return;
159 contents
->SetSaveFormData(Java_AwSettings_getSaveFormDataLocked(env
, obj
));
162 void AwSettings::RenderViewCreated(content::RenderViewHost
* render_view_host
) {
163 // A single WebContents can normally have 0 to many RenderViewHost instances
164 // associated with it.
165 // This is important since there is only one RenderViewHostExt instance per
166 // WebContents (and not one RVHExt per RVH, as you might expect) and updating
167 // settings via RVHExt only ever updates the 'current' RVH.
168 // In android_webview we don't swap out the RVH on cross-site navigations, so
169 // we shouldn't have to deal with the multiple RVH per WebContents case. That
170 // in turn means that the newly created RVH is always the 'current' RVH
171 // (since we only ever go from 0 to 1 RVH instances) and hence the DCHECK.
172 DCHECK(web_contents()->GetRenderViewHost() == render_view_host
);
177 void AwSettings::WebContentsDestroyed(content::WebContents
* web_contents
) {
182 void AwSettings::PopulateFixedPreferences(WebPreferences
* web_prefs
) {
183 web_prefs
->shrinks_standalone_images_to_fit
= false;
184 web_prefs
->should_clear_document_background
= false;
187 void AwSettings::PopulateWebPreferences(WebPreferences
* web_prefs
) {
188 JNIEnv
* env
= base::android::AttachCurrentThread();
190 ScopedJavaLocalRef
<jobject
> scoped_obj
= aw_settings_
.get(env
);
191 jobject obj
= scoped_obj
.obj();
193 // Grab the lock and call PopulateWebPreferencesLocked.
194 Java_AwSettings_populateWebPreferences(
195 env
, obj
, reinterpret_cast<jlong
>(web_prefs
));
198 void AwSettings::PopulateWebPreferencesLocked(
199 JNIEnv
* env
, jobject obj
, jlong web_prefs_ptr
) {
200 AwRenderViewHostExt
* render_view_host_ext
= GetAwRenderViewHostExt();
201 if (!render_view_host_ext
) return;
203 WebPreferences
* web_prefs
= reinterpret_cast<WebPreferences
*>(web_prefs_ptr
);
204 PopulateFixedPreferences(web_prefs
);
206 web_prefs
->text_autosizing_enabled
=
207 Java_AwSettings_getTextAutosizingEnabledLocked(env
, obj
);
209 int text_size_percent
= Java_AwSettings_getTextSizePercentLocked(env
, obj
);
210 if (web_prefs
->text_autosizing_enabled
) {
211 web_prefs
->font_scale_factor
= text_size_percent
/ 100.0f
;
212 web_prefs
->force_enable_zoom
= text_size_percent
>= 130;
213 // Use the default zoom factor value when Text Autosizer is turned on.
214 render_view_host_ext
->SetTextZoomFactor(1);
216 web_prefs
->force_enable_zoom
= false;
217 render_view_host_ext
->SetTextZoomFactor(text_size_percent
/ 100.0f
);
220 web_prefs
->standard_font_family_map
[webkit_glue::kCommonScript
] =
221 ConvertJavaStringToUTF16(
222 Java_AwSettings_getStandardFontFamilyLocked(env
, obj
));
224 web_prefs
->fixed_font_family_map
[webkit_glue::kCommonScript
] =
225 ConvertJavaStringToUTF16(
226 Java_AwSettings_getFixedFontFamilyLocked(env
, obj
));
228 web_prefs
->sans_serif_font_family_map
[webkit_glue::kCommonScript
] =
229 ConvertJavaStringToUTF16(
230 Java_AwSettings_getSansSerifFontFamilyLocked(env
, obj
));
232 web_prefs
->serif_font_family_map
[webkit_glue::kCommonScript
] =
233 ConvertJavaStringToUTF16(
234 Java_AwSettings_getSerifFontFamilyLocked(env
, obj
));
236 web_prefs
->cursive_font_family_map
[webkit_glue::kCommonScript
] =
237 ConvertJavaStringToUTF16(
238 Java_AwSettings_getCursiveFontFamilyLocked(env
, obj
));
240 web_prefs
->fantasy_font_family_map
[webkit_glue::kCommonScript
] =
241 ConvertJavaStringToUTF16(
242 Java_AwSettings_getFantasyFontFamilyLocked(env
, obj
));
244 web_prefs
->default_encoding
= ConvertJavaStringToUTF8(
245 Java_AwSettings_getDefaultTextEncodingLocked(env
, obj
));
247 web_prefs
->minimum_font_size
=
248 Java_AwSettings_getMinimumFontSizeLocked(env
, obj
);
250 web_prefs
->minimum_logical_font_size
=
251 Java_AwSettings_getMinimumLogicalFontSizeLocked(env
, obj
);
253 web_prefs
->default_font_size
=
254 Java_AwSettings_getDefaultFontSizeLocked(env
, obj
);
256 web_prefs
->default_fixed_font_size
=
257 Java_AwSettings_getDefaultFixedFontSizeLocked(env
, obj
);
259 // Blink's LoadsImagesAutomatically and ImagesEnabled must be
260 // set cris-cross to Android's. See
261 // https://code.google.com/p/chromium/issues/detail?id=224317#c26
262 web_prefs
->loads_images_automatically
=
263 Java_AwSettings_getImagesEnabledLocked(env
, obj
);
264 web_prefs
->images_enabled
=
265 Java_AwSettings_getLoadsImagesAutomaticallyLocked(env
, obj
);
267 web_prefs
->javascript_enabled
=
268 Java_AwSettings_getJavaScriptEnabledLocked(env
, obj
);
270 web_prefs
->allow_universal_access_from_file_urls
=
271 Java_AwSettings_getAllowUniversalAccessFromFileURLsLocked(env
, obj
);
273 web_prefs
->allow_file_access_from_file_urls
=
274 Java_AwSettings_getAllowFileAccessFromFileURLsLocked(env
, obj
);
276 web_prefs
->javascript_can_open_windows_automatically
=
277 Java_AwSettings_getJavaScriptCanOpenWindowsAutomaticallyLocked(env
, obj
);
279 web_prefs
->supports_multiple_windows
=
280 Java_AwSettings_getSupportMultipleWindowsLocked(env
, obj
);
282 web_prefs
->plugins_enabled
=
283 !Java_AwSettings_getPluginsDisabledLocked(env
, obj
);
285 web_prefs
->application_cache_enabled
=
286 Java_AwSettings_getAppCacheEnabledLocked(env
, obj
);
288 web_prefs
->local_storage_enabled
=
289 Java_AwSettings_getDomStorageEnabledLocked(env
, obj
);
291 web_prefs
->databases_enabled
=
292 Java_AwSettings_getDatabaseEnabledLocked(env
, obj
);
294 web_prefs
->wide_viewport_quirk
= true;
295 web_prefs
->use_wide_viewport
=
296 Java_AwSettings_getUseWideViewportLocked(env
, obj
);
298 web_prefs
->double_tap_to_zoom_enabled
=
299 Java_AwSettings_supportsDoubleTapZoomLocked(env
, obj
);
301 web_prefs
->initialize_at_minimum_page_scale
=
302 Java_AwSettings_getLoadWithOverviewModeLocked(env
, obj
);
304 web_prefs
->user_gesture_required_for_media_playback
=
305 Java_AwSettings_getMediaPlaybackRequiresUserGestureLocked(env
, obj
);
307 ScopedJavaLocalRef
<jstring
> url
=
308 Java_AwSettings_getDefaultVideoPosterURLLocked(env
, obj
);
309 web_prefs
->default_video_poster_url
= url
.obj() ?
310 GURL(ConvertJavaStringToUTF8(url
)) : GURL();
312 bool support_quirks
= Java_AwSettings_getSupportLegacyQuirksLocked(env
, obj
);
313 // Please see the corresponding Blink settings for bug references.
314 web_prefs
->support_deprecated_target_density_dpi
= support_quirks
;
315 web_prefs
->use_legacy_background_size_shorthand_behavior
= support_quirks
;
316 web_prefs
->viewport_meta_layout_size_quirk
= support_quirks
;
317 web_prefs
->viewport_meta_merge_content_quirk
= support_quirks
;
318 web_prefs
->viewport_meta_non_user_scalable_quirk
= support_quirks
;
319 web_prefs
->viewport_meta_zero_values_quirk
= support_quirks
;
320 web_prefs
->clobber_user_agent_initial_scale_quirk
= support_quirks
;
321 web_prefs
->ignore_main_frame_overflow_hidden_quirk
= support_quirks
;
322 web_prefs
->report_screen_size_in_physical_pixels_quirk
= support_quirks
;
324 web_prefs
->password_echo_enabled
=
325 Java_AwSettings_getPasswordEchoEnabledLocked(env
, obj
);
326 web_prefs
->spatial_navigation_enabled
=
327 Java_AwSettings_getSpatialNavigationLocked(env
, obj
);
329 web_prefs
->accelerated_2d_canvas_enabled
=
330 !accelerated_2d_canvas_disabled_by_switch_
&&
331 Java_AwSettings_getEnableSupportedHardwareAcceleratedFeaturesLocked(
335 static jlong
Init(JNIEnv
* env
,
337 jlong web_contents
) {
338 AwSettings
* settings
= new AwSettings(env
, obj
, web_contents
);
339 return reinterpret_cast<intptr_t>(settings
);
342 static jstring
GetDefaultUserAgent(JNIEnv
* env
, jclass clazz
) {
343 return base::android::ConvertUTF8ToJavaString(env
, GetUserAgent()).Release();
346 bool RegisterAwSettings(JNIEnv
* env
) {
347 return RegisterNativesImpl(env
) >= 0;
350 } // namespace android_webview