[Android] Fixed chrome://history's overlapped search and clear(x) icons on RTL
[chromium-blink-merge.git] / android_webview / native / aw_settings.cc
blob8dd383ea2cc9c79c62b8260ec27cf7617690c027
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/native/aw_contents.h"
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_string.h"
11 #include "content/public/browser/navigation_controller.h"
12 #include "content/public/browser/navigation_entry.h"
13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/common/content_client.h"
16 #include "jni/AwSettings_jni.h"
17 #include "webkit/glue/webkit_glue.h"
18 #include "webkit/glue/webpreferences.h"
19 #include "webkit/user_agent/user_agent.h"
21 using base::android::CheckException;
22 using base::android::ConvertJavaStringToUTF16;
23 using base::android::ConvertUTF16ToJavaString;
24 using base::android::ConvertUTF8ToJavaString;
25 using base::android::GetClass;
26 using base::android::GetFieldID;
27 using base::android::GetMethodIDFromClassName;
28 using base::android::ScopedJavaLocalRef;
30 namespace android_webview {
32 struct AwSettings::FieldIds {
33 // Note on speed. One may think that an approach that reads field values via
34 // JNI is ineffective and should not be used. Please keep in mind that in the
35 // legacy WebView the whole Sync method took <1ms on Xoom, and no one is
36 // expected to modify settings in performance-critical code.
37 FieldIds() { }
39 FieldIds(JNIEnv* env) {
40 const char* kStringClassName = "Ljava/lang/String;";
42 // FIXME: we should be using a new GetFieldIDFromClassName() with caching.
43 ScopedJavaLocalRef<jclass> clazz(
44 GetClass(env, "org/chromium/android_webview/AwSettings"));
45 text_size_percent = GetFieldID(env, clazz, "mTextSizePercent", "I");
46 standard_fond_family =
47 GetFieldID(env, clazz, "mStandardFontFamily", kStringClassName);
48 fixed_font_family =
49 GetFieldID(env, clazz, "mFixedFontFamily", kStringClassName);
50 sans_serif_font_family =
51 GetFieldID(env, clazz, "mSansSerifFontFamily", kStringClassName);
52 serif_font_family =
53 GetFieldID(env, clazz, "mSerifFontFamily", kStringClassName);
54 cursive_font_family =
55 GetFieldID(env, clazz, "mCursiveFontFamily", kStringClassName);
56 fantasy_font_family =
57 GetFieldID(env, clazz, "mFantasyFontFamily", kStringClassName);
58 default_text_encoding =
59 GetFieldID(env, clazz, "mDefaultTextEncoding", kStringClassName);
60 user_agent =
61 GetFieldID(env, clazz, "mUserAgent", kStringClassName);
62 minimum_font_size = GetFieldID(env, clazz, "mMinimumFontSize", "I");
63 minimum_logical_font_size =
64 GetFieldID(env, clazz, "mMinimumLogicalFontSize", "I");
65 default_font_size = GetFieldID(env, clazz, "mDefaultFontSize", "I");
66 default_fixed_font_size =
67 GetFieldID(env, clazz, "mDefaultFixedFontSize", "I");
68 load_images_automatically =
69 GetFieldID(env, clazz, "mLoadsImagesAutomatically", "Z");
70 images_enabled =
71 GetFieldID(env, clazz, "mImagesEnabled", "Z");
72 java_script_enabled =
73 GetFieldID(env, clazz, "mJavaScriptEnabled", "Z");
74 allow_universal_access_from_file_urls =
75 GetFieldID(env, clazz, "mAllowUniversalAccessFromFileURLs", "Z");
76 allow_file_access_from_file_urls =
77 GetFieldID(env, clazz, "mAllowFileAccessFromFileURLs", "Z");
78 java_script_can_open_windows_automatically =
79 GetFieldID(env, clazz, "mJavaScriptCanOpenWindowsAutomatically", "Z");
80 support_multiple_windows =
81 GetFieldID(env, clazz, "mSupportMultipleWindows", "Z");
82 dom_storage_enabled =
83 GetFieldID(env, clazz, "mDomStorageEnabled", "Z");
84 database_enabled =
85 GetFieldID(env, clazz, "mDatabaseEnabled", "Z");
86 use_wide_viewport =
87 GetFieldID(env, clazz, "mUseWideViewport", "Z");
88 load_with_overview_mode =
89 GetFieldID(env, clazz, "mLoadWithOverviewMode", "Z");
90 media_playback_requires_user_gesture =
91 GetFieldID(env, clazz, "mMediaPlaybackRequiresUserGesture", "Z");
92 default_video_poster_url =
93 GetFieldID(env, clazz, "mDefaultVideoPosterURL", kStringClassName);
94 support_deprecated_target_density_dpi =
95 GetFieldID(env, clazz, "mSupportDeprecatedTargetDensityDPI", "Z");
96 dip_scale =
97 GetFieldID(env, clazz, "mDIPScale", "D");
98 initial_page_scale_percent =
99 GetFieldID(env, clazz, "mInitialPageScalePercent", "F");
102 // Field ids
103 jfieldID text_size_percent;
104 jfieldID standard_fond_family;
105 jfieldID fixed_font_family;
106 jfieldID sans_serif_font_family;
107 jfieldID serif_font_family;
108 jfieldID cursive_font_family;
109 jfieldID fantasy_font_family;
110 jfieldID default_text_encoding;
111 jfieldID user_agent;
112 jfieldID minimum_font_size;
113 jfieldID minimum_logical_font_size;
114 jfieldID default_font_size;
115 jfieldID default_fixed_font_size;
116 jfieldID load_images_automatically;
117 jfieldID images_enabled;
118 jfieldID java_script_enabled;
119 jfieldID allow_universal_access_from_file_urls;
120 jfieldID allow_file_access_from_file_urls;
121 jfieldID java_script_can_open_windows_automatically;
122 jfieldID support_multiple_windows;
123 jfieldID dom_storage_enabled;
124 jfieldID database_enabled;
125 jfieldID use_wide_viewport;
126 jfieldID load_with_overview_mode;
127 jfieldID media_playback_requires_user_gesture;
128 jfieldID default_video_poster_url;
129 jfieldID support_deprecated_target_density_dpi;
130 jfieldID dip_scale;
131 jfieldID initial_page_scale_percent;
134 AwSettings::AwSettings(JNIEnv* env, jobject obj)
135 : aw_settings_(env, obj) {
138 AwSettings::~AwSettings() {
141 void AwSettings::Destroy(JNIEnv* env, jobject obj) {
142 delete this;
145 AwRenderViewHostExt* AwSettings::GetAwRenderViewHostExt() {
146 if (!web_contents()) return NULL;
147 AwContents* contents = AwContents::FromWebContents(web_contents());
148 if (!contents) return NULL;
149 return contents->render_view_host_ext();
152 void AwSettings::ResetScrollAndScaleState(JNIEnv* env, jobject obj) {
153 AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
154 if (!rvhe) return;
155 rvhe->ResetScrollAndScaleState();
158 void AwSettings::SetWebContents(JNIEnv* env, jobject obj, jint jweb_contents) {
159 content::WebContents* web_contents =
160 reinterpret_cast<content::WebContents*>(jweb_contents);
161 Observe(web_contents);
163 UpdateEverything(env, obj);
166 void AwSettings::UpdateEverything() {
167 JNIEnv* env = base::android::AttachCurrentThread();
168 CHECK(env);
169 ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
170 jobject obj = scoped_obj.obj();
171 if (!obj) return;
172 UpdateEverything(env, obj);
175 void AwSettings::UpdateEverything(JNIEnv* env, jobject obj) {
176 UpdateInitialPageScale(env, obj);
177 UpdateWebkitPreferences(env, obj);
178 UpdateUserAgent(env, obj);
179 ResetScrollAndScaleState(env, obj);
180 UpdatePreferredSizeMode();
183 void AwSettings::UpdateUserAgent(JNIEnv* env, jobject obj) {
184 if (!web_contents()) return;
186 if (!field_ids_)
187 field_ids_.reset(new FieldIds(env));
189 ScopedJavaLocalRef<jstring> str(env, static_cast<jstring>(
190 env->GetObjectField(obj, field_ids_->user_agent)));
191 bool ua_overidden = str.obj() != NULL;
193 if (ua_overidden) {
194 std::string override = base::android::ConvertJavaStringToUTF8(str);
195 web_contents()->SetUserAgentOverride(override);
198 const content::NavigationController& controller =
199 web_contents()->GetController();
200 for (int i = 0; i < controller.GetEntryCount(); ++i)
201 controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(ua_overidden);
204 void AwSettings::UpdateWebkitPreferences(JNIEnv* env, jobject obj) {
205 if (!web_contents()) return;
206 AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt();
207 if (!render_view_host_ext) return;
209 if (!field_ids_)
210 field_ids_.reset(new FieldIds(env));
212 content::RenderViewHost* render_view_host =
213 web_contents()->GetRenderViewHost();
214 if (!render_view_host) return;
215 WebPreferences prefs = render_view_host->GetWebkitPreferences();
217 prefs.text_autosizing_enabled =
218 Java_AwSettings_getTextAutosizingEnabled(env, obj);
220 int text_size_percent = env->GetIntField(obj, field_ids_->text_size_percent);
221 if (prefs.text_autosizing_enabled) {
222 prefs.font_scale_factor = text_size_percent / 100.0f;
223 prefs.force_enable_zoom = text_size_percent >= 130;
224 // Use the default zoom level value when Text Autosizer is turned on.
225 render_view_host_ext->SetTextZoomLevel(0);
226 } else {
227 prefs.force_enable_zoom = false;
228 render_view_host_ext->SetTextZoomLevel(webkit_glue::ZoomFactorToZoomLevel(
229 text_size_percent / 100.0f));
232 ScopedJavaLocalRef<jstring> str(
233 env, static_cast<jstring>(
234 env->GetObjectField(obj, field_ids_->standard_fond_family)));
235 prefs.standard_font_family_map[webkit_glue::kCommonScript] =
236 ConvertJavaStringToUTF16(str);
238 str.Reset(
239 env, static_cast<jstring>(
240 env->GetObjectField(obj, field_ids_->fixed_font_family)));
241 prefs.fixed_font_family_map[webkit_glue::kCommonScript] =
242 ConvertJavaStringToUTF16(str);
244 str.Reset(
245 env, static_cast<jstring>(
246 env->GetObjectField(obj, field_ids_->sans_serif_font_family)));
247 prefs.sans_serif_font_family_map[webkit_glue::kCommonScript] =
248 ConvertJavaStringToUTF16(str);
250 str.Reset(
251 env, static_cast<jstring>(
252 env->GetObjectField(obj, field_ids_->serif_font_family)));
253 prefs.serif_font_family_map[webkit_glue::kCommonScript] =
254 ConvertJavaStringToUTF16(str);
256 str.Reset(
257 env, static_cast<jstring>(
258 env->GetObjectField(obj, field_ids_->cursive_font_family)));
259 prefs.cursive_font_family_map[webkit_glue::kCommonScript] =
260 ConvertJavaStringToUTF16(str);
262 str.Reset(
263 env, static_cast<jstring>(
264 env->GetObjectField(obj, field_ids_->fantasy_font_family)));
265 prefs.fantasy_font_family_map[webkit_glue::kCommonScript] =
266 ConvertJavaStringToUTF16(str);
268 str.Reset(
269 env, static_cast<jstring>(
270 env->GetObjectField(obj, field_ids_->default_text_encoding)));
271 prefs.default_encoding = ConvertJavaStringToUTF8(str);
273 prefs.minimum_font_size =
274 env->GetIntField(obj, field_ids_->minimum_font_size);
276 prefs.minimum_logical_font_size =
277 env->GetIntField(obj, field_ids_->minimum_logical_font_size);
279 prefs.default_font_size =
280 env->GetIntField(obj, field_ids_->default_font_size);
282 prefs.default_fixed_font_size =
283 env->GetIntField(obj, field_ids_->default_fixed_font_size);
285 prefs.loads_images_automatically =
286 env->GetBooleanField(obj, field_ids_->load_images_automatically);
288 prefs.images_enabled =
289 env->GetBooleanField(obj, field_ids_->images_enabled);
291 prefs.javascript_enabled =
292 env->GetBooleanField(obj, field_ids_->java_script_enabled);
294 prefs.allow_universal_access_from_file_urls = env->GetBooleanField(
295 obj, field_ids_->allow_universal_access_from_file_urls);
297 prefs.allow_file_access_from_file_urls = env->GetBooleanField(
298 obj, field_ids_->allow_file_access_from_file_urls);
300 prefs.javascript_can_open_windows_automatically = env->GetBooleanField(
301 obj, field_ids_->java_script_can_open_windows_automatically);
303 prefs.supports_multiple_windows = env->GetBooleanField(
304 obj, field_ids_->support_multiple_windows);
306 prefs.plugins_enabled = !Java_AwSettings_getPluginsDisabled(env, obj);
308 prefs.application_cache_enabled =
309 Java_AwSettings_getAppCacheEnabled(env, obj);
311 prefs.local_storage_enabled = env->GetBooleanField(
312 obj, field_ids_->dom_storage_enabled);
314 prefs.databases_enabled = env->GetBooleanField(
315 obj, field_ids_->database_enabled);
317 prefs.double_tap_to_zoom_enabled = prefs.use_wide_viewport =
318 env->GetBooleanField(obj, field_ids_->use_wide_viewport);
320 prefs.initialize_at_minimum_page_scale = env->GetBooleanField(
321 obj, field_ids_->load_with_overview_mode);
323 prefs.user_gesture_required_for_media_playback = env->GetBooleanField(
324 obj, field_ids_->media_playback_requires_user_gesture);
326 str.Reset(
327 env, static_cast<jstring>(
328 env->GetObjectField(obj, field_ids_->default_video_poster_url)));
329 prefs.default_video_poster_url = str.obj() ?
330 GURL(ConvertJavaStringToUTF8(str)) : GURL();
332 prefs.support_deprecated_target_density_dpi = env->GetBooleanField(
333 obj, field_ids_->support_deprecated_target_density_dpi);
335 render_view_host->UpdateWebkitPreferences(prefs);
338 void AwSettings::UpdateInitialPageScale(JNIEnv* env, jobject obj) {
339 AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
340 if (!rvhe) return;
342 if (!field_ids_)
343 field_ids_.reset(new FieldIds(env));
345 float initial_page_scale_percent =
346 env->GetFloatField(obj, field_ids_->initial_page_scale_percent);
347 if (initial_page_scale_percent == 0) {
348 rvhe->SetInitialPageScale(-1);
349 } else {
350 float dip_scale = static_cast<float>(
351 env->GetDoubleField(obj, field_ids_->dip_scale));
352 rvhe->SetInitialPageScale(initial_page_scale_percent / dip_scale / 100.0f);
356 void AwSettings::UpdatePreferredSizeMode() {
357 if (web_contents()->GetRenderViewHost()) {
358 web_contents()->GetRenderViewHost()->EnablePreferredSizeMode();
362 void AwSettings::RenderViewCreated(content::RenderViewHost* render_view_host) {
363 // A single WebContents can normally have 0 to many RenderViewHost instances
364 // associated with it.
365 // This is important since there is only one RenderViewHostExt instance per
366 // WebContents (and not one RVHExt per RVH, as you might expect) and updating
367 // settings via RVHExt only ever updates the 'current' RVH.
368 // In android_webview we don't swap out the RVH on cross-site navigations, so
369 // we shouldn't have to deal with the multiple RVH per WebContents case. That
370 // in turn means that the newly created RVH is always the 'current' RVH
371 // (since we only ever go from 0 to 1 RVH instances) and hence the DCHECK.
372 DCHECK(web_contents()->GetRenderViewHost() == render_view_host);
374 UpdateEverything();
377 static jint Init(JNIEnv* env,
378 jobject obj,
379 jint web_contents) {
380 AwSettings* settings = new AwSettings(env, obj);
381 settings->SetWebContents(env, obj, web_contents);
382 return reinterpret_cast<jint>(settings);
385 static jstring GetDefaultUserAgent(JNIEnv* env, jclass clazz) {
386 return base::android::ConvertUTF8ToJavaString(
387 env, content::GetUserAgent(GURL())).Release();
390 bool RegisterAwSettings(JNIEnv* env) {
391 return RegisterNativesImpl(env) >= 0;
394 } // namespace android_webview