GPU workaround to simulate Out of Memory errors with large textures
[chromium-blink-merge.git] / android_webview / native / aw_settings.cc
blobc0674f511b00f3369a5f0a27772abafbff89382d
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/macros.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/renderer_preferences.h"
19 #include "content/public/common/web_preferences.h"
20 #include "jni/AwSettings_jni.h"
21 #include "ui/gfx/font_render_params.h"
23 using base::android::ConvertJavaStringToUTF16;
24 using base::android::ConvertUTF8ToJavaString;
25 using base::android::ScopedJavaLocalRef;
26 using content::RendererPreferences;
27 using content::WebPreferences;
29 namespace android_webview {
31 namespace {
33 void PopulateFixedRendererPreferences(RendererPreferences* prefs) {
34 prefs->tap_multiple_targets_strategy =
35 content::TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
37 // TODO(boliu): Deduplicate with chrome/ code.
38 CR_DEFINE_STATIC_LOCAL(const gfx::FontRenderParams, params,
39 (gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), NULL)));
40 prefs->should_antialias_text = params.antialiasing;
41 prefs->use_subpixel_positioning = params.subpixel_positioning;
42 prefs->hinting = params.hinting;
43 prefs->use_autohinter = params.autohinter;
44 prefs->use_bitmaps = params.use_bitmaps;
45 prefs->subpixel_rendering = params.subpixel_rendering;
48 void PopulateFixedWebPreferences(WebPreferences* web_prefs) {
49 web_prefs->shrinks_standalone_images_to_fit = false;
50 web_prefs->should_clear_document_background = false;
53 }; // namespace
55 const void* kAwSettingsUserDataKey = &kAwSettingsUserDataKey;
57 class AwSettingsUserData : public base::SupportsUserData::Data {
58 public:
59 AwSettingsUserData(AwSettings* ptr) : settings_(ptr) {}
61 static AwSettings* GetSettings(content::WebContents* web_contents) {
62 if (!web_contents)
63 return NULL;
64 AwSettingsUserData* data = static_cast<AwSettingsUserData*>(
65 web_contents->GetUserData(kAwSettingsUserDataKey));
66 return data ? data->settings_ : NULL;
69 private:
70 AwSettings* settings_;
73 AwSettings::AwSettings(JNIEnv* env,
74 jobject obj,
75 content::WebContents* web_contents)
76 : WebContentsObserver(web_contents),
77 renderer_prefs_initialized_(false),
78 aw_settings_(env, obj) {
79 web_contents->SetUserData(kAwSettingsUserDataKey,
80 new AwSettingsUserData(this));
83 AwSettings::~AwSettings() {
84 if (web_contents()) {
85 web_contents()->SetUserData(kAwSettingsUserDataKey, NULL);
88 JNIEnv* env = base::android::AttachCurrentThread();
89 ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
90 jobject obj = scoped_obj.obj();
91 if (!obj) return;
92 Java_AwSettings_nativeAwSettingsGone(env, obj,
93 reinterpret_cast<intptr_t>(this));
96 void AwSettings::Destroy(JNIEnv* env, jobject obj) {
97 delete this;
100 AwSettings* AwSettings::FromWebContents(content::WebContents* web_contents) {
101 return AwSettingsUserData::GetSettings(web_contents);
104 AwRenderViewHostExt* AwSettings::GetAwRenderViewHostExt() {
105 if (!web_contents()) return NULL;
106 AwContents* contents = AwContents::FromWebContents(web_contents());
107 if (!contents) return NULL;
108 return contents->render_view_host_ext();
111 void AwSettings::ResetScrollAndScaleState(JNIEnv* env, jobject obj) {
112 AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
113 if (!rvhe) return;
114 rvhe->ResetScrollAndScaleState();
117 void AwSettings::UpdateEverything() {
118 JNIEnv* env = base::android::AttachCurrentThread();
119 CHECK(env);
120 ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
121 jobject obj = scoped_obj.obj();
122 if (!obj) return;
123 // Grab the lock and call UpdateEverythingLocked.
124 Java_AwSettings_updateEverything(env, obj);
127 void AwSettings::UpdateEverythingLocked(JNIEnv* env, jobject obj) {
128 UpdateInitialPageScaleLocked(env, obj);
129 UpdateWebkitPreferencesLocked(env, obj);
130 UpdateUserAgentLocked(env, obj);
131 ResetScrollAndScaleState(env, obj);
132 UpdateFormDataPreferencesLocked(env, obj);
133 UpdateRendererPreferencesLocked(env, obj);
134 UpdateOffscreenPreRasterLocked(env, obj);
137 void AwSettings::UpdateUserAgentLocked(JNIEnv* env, jobject obj) {
138 if (!web_contents()) return;
140 ScopedJavaLocalRef<jstring> str =
141 Java_AwSettings_getUserAgentLocked(env, obj);
142 bool ua_overidden = str.obj() != NULL;
144 if (ua_overidden) {
145 std::string override = base::android::ConvertJavaStringToUTF8(str);
146 web_contents()->SetUserAgentOverride(override);
149 const content::NavigationController& controller =
150 web_contents()->GetController();
151 for (int i = 0; i < controller.GetEntryCount(); ++i)
152 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(ua_overidden);
155 void AwSettings::UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj) {
156 if (!web_contents()) return;
157 AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt();
158 if (!render_view_host_ext) return;
160 content::RenderViewHost* render_view_host =
161 web_contents()->GetRenderViewHost();
162 if (!render_view_host) return;
163 render_view_host->OnWebkitPreferencesChanged();
166 void AwSettings::UpdateInitialPageScaleLocked(JNIEnv* env, jobject obj) {
167 AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
168 if (!rvhe) return;
170 float initial_page_scale_percent =
171 Java_AwSettings_getInitialPageScalePercentLocked(env, obj);
172 if (initial_page_scale_percent == 0) {
173 rvhe->SetInitialPageScale(-1);
174 } else {
175 float dip_scale = static_cast<float>(
176 Java_AwSettings_getDIPScaleLocked(env, obj));
177 rvhe->SetInitialPageScale(initial_page_scale_percent / dip_scale / 100.0f);
181 void AwSettings::UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj) {
182 if (!web_contents()) return;
183 AwContents* contents = AwContents::FromWebContents(web_contents());
184 if (!contents) return;
186 contents->SetSaveFormData(Java_AwSettings_getSaveFormDataLocked(env, obj));
189 void AwSettings::UpdateRendererPreferencesLocked(JNIEnv* env, jobject obj) {
190 if (!web_contents()) return;
192 bool update_prefs = false;
193 RendererPreferences* prefs = web_contents()->GetMutableRendererPrefs();
195 if (!renderer_prefs_initialized_) {
196 PopulateFixedRendererPreferences(prefs);
197 renderer_prefs_initialized_ = true;
198 update_prefs = true;
201 bool video_overlay =
202 Java_AwSettings_getVideoOverlayForEmbeddedVideoEnabledLocked(env, obj);
203 bool force_video_overlay =
204 Java_AwSettings_getForceVideoOverlayForTests(env, obj);
205 if (video_overlay !=
206 prefs->use_video_overlay_for_embedded_encrypted_video ||
207 force_video_overlay != prefs->use_view_overlay_for_all_video) {
208 prefs->use_video_overlay_for_embedded_encrypted_video = video_overlay;
209 prefs->use_view_overlay_for_all_video = force_video_overlay;
210 update_prefs = true;
213 content::RenderViewHost* host = web_contents()->GetRenderViewHost();
214 if (update_prefs && host)
215 host->SyncRendererPrefs();
218 void AwSettings::UpdateOffscreenPreRasterLocked(JNIEnv* env, jobject obj) {
219 AwContents* contents = AwContents::FromWebContents(web_contents());
220 if (contents) {
221 contents->SetOffscreenPreRaster(
222 Java_AwSettings_getOffscreenPreRasterLocked(env, obj));
226 void AwSettings::RenderViewCreated(content::RenderViewHost* render_view_host) {
227 // A single WebContents can normally have 0 to many RenderViewHost instances
228 // associated with it.
229 // This is important since there is only one RenderViewHostExt instance per
230 // WebContents (and not one RVHExt per RVH, as you might expect) and updating
231 // settings via RVHExt only ever updates the 'current' RVH.
232 // In android_webview we don't swap out the RVH on cross-site navigations, so
233 // we shouldn't have to deal with the multiple RVH per WebContents case. That
234 // in turn means that the newly created RVH is always the 'current' RVH
235 // (since we only ever go from 0 to 1 RVH instances) and hence the DCHECK.
236 DCHECK_EQ(render_view_host, web_contents()->GetRenderViewHost());
238 UpdateEverything();
241 void AwSettings::WebContentsDestroyed() {
242 delete this;
245 void AwSettings::PopulateWebPreferences(WebPreferences* web_prefs) {
246 JNIEnv* env = base::android::AttachCurrentThread();
247 CHECK(env);
248 ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
249 jobject obj = scoped_obj.obj();
250 if (!obj) return;
251 // Grab the lock and call PopulateWebPreferencesLocked.
252 Java_AwSettings_populateWebPreferences(
253 env, obj, reinterpret_cast<jlong>(web_prefs));
256 void AwSettings::PopulateWebPreferencesLocked(
257 JNIEnv* env, jobject obj, jlong web_prefs_ptr) {
258 AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt();
259 if (!render_view_host_ext) return;
261 WebPreferences* web_prefs = reinterpret_cast<WebPreferences*>(web_prefs_ptr);
262 PopulateFixedWebPreferences(web_prefs);
264 web_prefs->text_autosizing_enabled =
265 Java_AwSettings_getTextAutosizingEnabledLocked(env, obj);
267 int text_size_percent = Java_AwSettings_getTextSizePercentLocked(env, obj);
268 if (web_prefs->text_autosizing_enabled) {
269 web_prefs->font_scale_factor = text_size_percent / 100.0f;
270 web_prefs->force_enable_zoom = text_size_percent >= 130;
271 // Use the default zoom factor value when Text Autosizer is turned on.
272 render_view_host_ext->SetTextZoomFactor(1);
273 } else {
274 web_prefs->force_enable_zoom = false;
275 render_view_host_ext->SetTextZoomFactor(text_size_percent / 100.0f);
278 web_prefs->standard_font_family_map[content::kCommonScript] =
279 ConvertJavaStringToUTF16(
280 Java_AwSettings_getStandardFontFamilyLocked(env, obj));
282 web_prefs->fixed_font_family_map[content::kCommonScript] =
283 ConvertJavaStringToUTF16(
284 Java_AwSettings_getFixedFontFamilyLocked(env, obj));
286 web_prefs->sans_serif_font_family_map[content::kCommonScript] =
287 ConvertJavaStringToUTF16(
288 Java_AwSettings_getSansSerifFontFamilyLocked(env, obj));
290 web_prefs->serif_font_family_map[content::kCommonScript] =
291 ConvertJavaStringToUTF16(
292 Java_AwSettings_getSerifFontFamilyLocked(env, obj));
294 web_prefs->cursive_font_family_map[content::kCommonScript] =
295 ConvertJavaStringToUTF16(
296 Java_AwSettings_getCursiveFontFamilyLocked(env, obj));
298 web_prefs->fantasy_font_family_map[content::kCommonScript] =
299 ConvertJavaStringToUTF16(
300 Java_AwSettings_getFantasyFontFamilyLocked(env, obj));
302 web_prefs->default_encoding = ConvertJavaStringToUTF8(
303 Java_AwSettings_getDefaultTextEncodingLocked(env, obj));
305 web_prefs->minimum_font_size =
306 Java_AwSettings_getMinimumFontSizeLocked(env, obj);
308 web_prefs->minimum_logical_font_size =
309 Java_AwSettings_getMinimumLogicalFontSizeLocked(env, obj);
311 web_prefs->default_font_size =
312 Java_AwSettings_getDefaultFontSizeLocked(env, obj);
314 web_prefs->default_fixed_font_size =
315 Java_AwSettings_getDefaultFixedFontSizeLocked(env, obj);
317 // Blink's LoadsImagesAutomatically and ImagesEnabled must be
318 // set cris-cross to Android's. See
319 // https://code.google.com/p/chromium/issues/detail?id=224317#c26
320 web_prefs->loads_images_automatically =
321 Java_AwSettings_getImagesEnabledLocked(env, obj);
322 web_prefs->images_enabled =
323 Java_AwSettings_getLoadsImagesAutomaticallyLocked(env, obj);
325 web_prefs->javascript_enabled =
326 Java_AwSettings_getJavaScriptEnabledLocked(env, obj);
328 web_prefs->allow_universal_access_from_file_urls =
329 Java_AwSettings_getAllowUniversalAccessFromFileURLsLocked(env, obj);
331 web_prefs->allow_file_access_from_file_urls =
332 Java_AwSettings_getAllowFileAccessFromFileURLsLocked(env, obj);
334 web_prefs->javascript_can_open_windows_automatically =
335 Java_AwSettings_getJavaScriptCanOpenWindowsAutomaticallyLocked(env, obj);
337 web_prefs->supports_multiple_windows =
338 Java_AwSettings_getSupportMultipleWindowsLocked(env, obj);
340 web_prefs->plugins_enabled =
341 !Java_AwSettings_getPluginsDisabledLocked(env, obj);
343 web_prefs->application_cache_enabled =
344 Java_AwSettings_getAppCacheEnabledLocked(env, obj);
346 web_prefs->local_storage_enabled =
347 Java_AwSettings_getDomStorageEnabledLocked(env, obj);
349 web_prefs->databases_enabled =
350 Java_AwSettings_getDatabaseEnabledLocked(env, obj);
352 web_prefs->wide_viewport_quirk = true;
353 web_prefs->use_wide_viewport =
354 Java_AwSettings_getUseWideViewportLocked(env, obj);
356 web_prefs->force_zero_layout_height =
357 Java_AwSettings_getForceZeroLayoutHeightLocked(env, obj);
359 const bool zero_layout_height_disables_viewport_quirk =
360 Java_AwSettings_getZeroLayoutHeightDisablesViewportQuirkLocked(env, obj);
361 web_prefs->viewport_enabled = !(zero_layout_height_disables_viewport_quirk &&
362 web_prefs->force_zero_layout_height);
364 web_prefs->double_tap_to_zoom_enabled =
365 Java_AwSettings_supportsDoubleTapZoomLocked(env, obj);
367 web_prefs->initialize_at_minimum_page_scale =
368 Java_AwSettings_getLoadWithOverviewModeLocked(env, obj);
370 web_prefs->user_gesture_required_for_media_playback =
371 Java_AwSettings_getMediaPlaybackRequiresUserGestureLocked(env, obj);
373 ScopedJavaLocalRef<jstring> url =
374 Java_AwSettings_getDefaultVideoPosterURLLocked(env, obj);
375 web_prefs->default_video_poster_url = url.obj() ?
376 GURL(ConvertJavaStringToUTF8(url)) : GURL();
378 bool support_quirks = Java_AwSettings_getSupportLegacyQuirksLocked(env, obj);
379 // Please see the corresponding Blink settings for bug references.
380 web_prefs->support_deprecated_target_density_dpi = support_quirks;
381 web_prefs->use_legacy_background_size_shorthand_behavior = support_quirks;
382 web_prefs->viewport_meta_layout_size_quirk = support_quirks;
383 web_prefs->viewport_meta_merge_content_quirk = support_quirks;
384 web_prefs->viewport_meta_non_user_scalable_quirk = support_quirks;
385 web_prefs->viewport_meta_zero_values_quirk = support_quirks;
386 web_prefs->clobber_user_agent_initial_scale_quirk = support_quirks;
387 web_prefs->ignore_main_frame_overflow_hidden_quirk = support_quirks;
388 web_prefs->report_screen_size_in_physical_pixels_quirk = support_quirks;
390 web_prefs->password_echo_enabled =
391 Java_AwSettings_getPasswordEchoEnabledLocked(env, obj);
392 web_prefs->spatial_navigation_enabled =
393 Java_AwSettings_getSpatialNavigationLocked(env, obj);
395 bool enable_supported_hardware_accelerated_features =
396 Java_AwSettings_getEnableSupportedHardwareAcceleratedFeaturesLocked(
397 env, obj);
399 bool accelerated_2d_canvas_enabled_by_switch =
400 web_prefs->accelerated_2d_canvas_enabled;
401 web_prefs->accelerated_2d_canvas_enabled = true;
402 if (!accelerated_2d_canvas_enabled_by_switch ||
403 !enable_supported_hardware_accelerated_features) {
404 // Any canvas smaller than this will fallback to software. Abusing this
405 // slightly to turn canvas off without changing
406 // accelerated_2d_canvas_enabled, which also affects compositing mode.
407 // Using 100M instead of max int to avoid overflows.
408 web_prefs->minimum_accelerated_2d_canvas_size = 100 * 1000 * 1000;
410 web_prefs->experimental_webgl_enabled =
411 web_prefs->experimental_webgl_enabled &&
412 enable_supported_hardware_accelerated_features;
414 web_prefs->allow_displaying_insecure_content =
415 Java_AwSettings_getAllowDisplayingInsecureContentLocked(env, obj);
416 web_prefs->allow_running_insecure_content =
417 Java_AwSettings_getAllowRunningInsecureContentLocked(env, obj);
419 web_prefs->fullscreen_supported =
420 Java_AwSettings_getFullscreenSupportedLocked(env, obj);
423 static jlong Init(JNIEnv* env,
424 jobject obj,
425 jobject web_contents) {
426 content::WebContents* contents = content::WebContents::FromJavaWebContents(
427 web_contents);
428 AwSettings* settings = new AwSettings(env, obj, contents);
429 return reinterpret_cast<intptr_t>(settings);
432 static jstring GetDefaultUserAgent(JNIEnv* env, jclass clazz) {
433 return base::android::ConvertUTF8ToJavaString(env, GetUserAgent()).Release();
436 bool RegisterAwSettings(JNIEnv* env) {
437 return RegisterNativesImpl(env);
440 } // namespace android_webview