- add sources.
[platform/framework/web/crosswalk.git] / src / android_webview / native / aw_settings.cc
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/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 "base/supports_user_data.h"
12 #include "content/public/browser/navigation_controller.h"
13 #include "content/public/browser/navigation_entry.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/common/content_client.h"
17 #include "jni/AwSettings_jni.h"
18 #include "webkit/common/user_agent/user_agent.h"
19 #include "webkit/common/webpreferences.h"
20 #include "webkit/glue/webkit_glue.h"
21
22 using base::android::ConvertJavaStringToUTF16;
23 using base::android::ConvertUTF8ToJavaString;
24 using base::android::ScopedJavaLocalRef;
25
26 namespace android_webview {
27
28 const void* kAwSettingsUserDataKey = &kAwSettingsUserDataKey;
29
30 class AwSettingsUserData : public base::SupportsUserData::Data {
31  public:
32   AwSettingsUserData(AwSettings* ptr) : settings_(ptr) {}
33
34   static AwSettings* GetSettings(content::WebContents* web_contents) {
35     if (!web_contents)
36       return NULL;
37     AwSettingsUserData* data = reinterpret_cast<AwSettingsUserData*>(
38         web_contents->GetUserData(kAwSettingsUserDataKey));
39     return data ? data->settings_ : NULL;
40   }
41
42  private:
43   AwSettings* settings_;
44 };
45
46 AwSettings::AwSettings(JNIEnv* env, jobject obj, jint web_contents)
47     : WebContentsObserver(
48           reinterpret_cast<content::WebContents*>(web_contents)),
49       aw_settings_(env, obj) {
50   reinterpret_cast<content::WebContents*>(web_contents)->
51       SetUserData(kAwSettingsUserDataKey, new AwSettingsUserData(this));
52 }
53
54 AwSettings::~AwSettings() {
55   if (web_contents()) {
56     web_contents()->SetUserData(kAwSettingsUserDataKey, NULL);
57   }
58
59   JNIEnv* env = base::android::AttachCurrentThread();
60   ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
61   jobject obj = scoped_obj.obj();
62   if (!obj) return;
63   Java_AwSettings_nativeAwSettingsGone(env, obj,
64                                        reinterpret_cast<jint>(this));
65 }
66
67 void AwSettings::Destroy(JNIEnv* env, jobject obj) {
68   delete this;
69 }
70
71 AwSettings* AwSettings::FromWebContents(content::WebContents* web_contents) {
72   return AwSettingsUserData::GetSettings(web_contents);
73 }
74
75 AwRenderViewHostExt* AwSettings::GetAwRenderViewHostExt() {
76   if (!web_contents()) return NULL;
77   AwContents* contents = AwContents::FromWebContents(web_contents());
78   if (!contents) return NULL;
79   return contents->render_view_host_ext();
80 }
81
82 void AwSettings::ResetScrollAndScaleState(JNIEnv* env, jobject obj) {
83   AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
84   if (!rvhe) return;
85   rvhe->ResetScrollAndScaleState();
86 }
87
88 void AwSettings::UpdateEverything() {
89   JNIEnv* env = base::android::AttachCurrentThread();
90   CHECK(env);
91   ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
92   jobject obj = scoped_obj.obj();
93   if (!obj) return;
94   // Grab the lock and call UpdateEverythingLocked.
95   Java_AwSettings_updateEverything(env, obj);
96 }
97
98 void AwSettings::UpdateEverythingLocked(JNIEnv* env, jobject obj) {
99   UpdateInitialPageScaleLocked(env, obj);
100   UpdateWebkitPreferencesLocked(env, obj);
101   UpdateUserAgentLocked(env, obj);
102   ResetScrollAndScaleState(env, obj);
103   UpdateFormDataPreferencesLocked(env, obj);
104 }
105
106 void AwSettings::UpdateUserAgentLocked(JNIEnv* env, jobject obj) {
107   if (!web_contents()) return;
108
109   ScopedJavaLocalRef<jstring> str =
110       Java_AwSettings_getUserAgentLocked(env, obj);
111   bool ua_overidden = str.obj() != NULL;
112
113   if (ua_overidden) {
114     std::string override = base::android::ConvertJavaStringToUTF8(str);
115     web_contents()->SetUserAgentOverride(override);
116   }
117
118   const content::NavigationController& controller =
119       web_contents()->GetController();
120   for (int i = 0; i < controller.GetEntryCount(); ++i)
121     controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(ua_overidden);
122 }
123
124 void AwSettings::UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj) {
125   if (!web_contents()) return;
126   AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt();
127   if (!render_view_host_ext) return;
128
129   content::RenderViewHost* render_view_host =
130       web_contents()->GetRenderViewHost();
131   if (!render_view_host) return;
132   render_view_host->UpdateWebkitPreferences(
133       render_view_host->GetWebkitPreferences());
134 }
135
136 void AwSettings::UpdateInitialPageScaleLocked(JNIEnv* env, jobject obj) {
137   AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
138   if (!rvhe) return;
139
140   float initial_page_scale_percent =
141       Java_AwSettings_getInitialPageScalePercentLocked(env, obj);
142   if (initial_page_scale_percent == 0) {
143     rvhe->SetInitialPageScale(-1);
144   } else {
145     float dip_scale = static_cast<float>(
146         Java_AwSettings_getDIPScaleLocked(env, obj));
147     rvhe->SetInitialPageScale(initial_page_scale_percent / dip_scale / 100.0f);
148   }
149 }
150
151 void AwSettings::UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj) {
152   if (!web_contents()) return;
153   AwContents* contents = AwContents::FromWebContents(web_contents());
154   if (!contents) return;
155
156   contents->SetSaveFormData(Java_AwSettings_getSaveFormDataLocked(env, obj));
157 }
158
159 void AwSettings::RenderViewCreated(content::RenderViewHost* render_view_host) {
160   // A single WebContents can normally have 0 to many RenderViewHost instances
161   // associated with it.
162   // This is important since there is only one RenderViewHostExt instance per
163   // WebContents (and not one RVHExt per RVH, as you might expect) and updating
164   // settings via RVHExt only ever updates the 'current' RVH.
165   // In android_webview we don't swap out the RVH on cross-site navigations, so
166   // we shouldn't have to deal with the multiple RVH per WebContents case. That
167   // in turn means that the newly created RVH is always the 'current' RVH
168   // (since we only ever go from 0 to 1 RVH instances) and hence the DCHECK.
169   DCHECK(web_contents()->GetRenderViewHost() == render_view_host);
170
171   UpdateEverything();
172 }
173
174 void AwSettings::WebContentsDestroyed(content::WebContents* web_contents) {
175   delete this;
176 }
177
178 // static
179 void AwSettings::PopulateFixedPreferences(WebPreferences* web_prefs) {
180   web_prefs->shrinks_standalone_images_to_fit = false;
181 }
182
183 void AwSettings::PopulateWebPreferences(WebPreferences* web_prefs) {
184   JNIEnv* env = base::android::AttachCurrentThread();
185   CHECK(env);
186
187   AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt();
188   if (!render_view_host_ext) return;
189
190   ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
191   jobject obj = scoped_obj.obj();
192   if (!obj) return;
193
194   PopulateFixedPreferences(web_prefs);
195
196   web_prefs->text_autosizing_enabled =
197       Java_AwSettings_getTextAutosizingEnabledLocked(env, obj);
198
199   int text_size_percent = Java_AwSettings_getTextSizePercentLocked(env, obj);
200   if (web_prefs->text_autosizing_enabled) {
201     web_prefs->font_scale_factor = text_size_percent / 100.0f;
202     web_prefs->force_enable_zoom = text_size_percent >= 130;
203     // Use the default zoom factor value when Text Autosizer is turned on.
204     render_view_host_ext->SetTextZoomFactor(1);
205   } else {
206     web_prefs->force_enable_zoom = false;
207     render_view_host_ext->SetTextZoomFactor(text_size_percent / 100.0f);
208   }
209
210   web_prefs->standard_font_family_map[webkit_glue::kCommonScript] =
211       ConvertJavaStringToUTF16(
212           Java_AwSettings_getStandardFontFamilyLocked(env, obj));
213
214   web_prefs->fixed_font_family_map[webkit_glue::kCommonScript] =
215       ConvertJavaStringToUTF16(
216           Java_AwSettings_getFixedFontFamilyLocked(env, obj));
217
218   web_prefs->sans_serif_font_family_map[webkit_glue::kCommonScript] =
219       ConvertJavaStringToUTF16(
220           Java_AwSettings_getSansSerifFontFamilyLocked(env, obj));
221
222   web_prefs->serif_font_family_map[webkit_glue::kCommonScript] =
223       ConvertJavaStringToUTF16(
224           Java_AwSettings_getSerifFontFamilyLocked(env, obj));
225
226   web_prefs->cursive_font_family_map[webkit_glue::kCommonScript] =
227       ConvertJavaStringToUTF16(
228           Java_AwSettings_getCursiveFontFamilyLocked(env, obj));
229
230   web_prefs->fantasy_font_family_map[webkit_glue::kCommonScript] =
231       ConvertJavaStringToUTF16(
232           Java_AwSettings_getFantasyFontFamilyLocked(env, obj));
233
234   web_prefs->default_encoding = ConvertJavaStringToUTF8(
235       Java_AwSettings_getDefaultTextEncodingLocked(env, obj));
236
237   web_prefs->minimum_font_size =
238       Java_AwSettings_getMinimumFontSizeLocked(env, obj);
239
240   web_prefs->minimum_logical_font_size =
241       Java_AwSettings_getMinimumLogicalFontSizeLocked(env, obj);
242
243   web_prefs->default_font_size =
244       Java_AwSettings_getDefaultFontSizeLocked(env, obj);
245
246   web_prefs->default_fixed_font_size =
247       Java_AwSettings_getDefaultFixedFontSizeLocked(env, obj);
248
249   // Blink's LoadsImagesAutomatically and ImagesEnabled must be
250   // set cris-cross to Android's. See
251   // https://code.google.com/p/chromium/issues/detail?id=224317#c26
252   web_prefs->loads_images_automatically =
253       Java_AwSettings_getImagesEnabledLocked(env, obj);
254   web_prefs->images_enabled =
255       Java_AwSettings_getLoadsImagesAutomaticallyLocked(env, obj);
256
257   web_prefs->javascript_enabled =
258       Java_AwSettings_getJavaScriptEnabledLocked(env, obj);
259
260   web_prefs->allow_universal_access_from_file_urls =
261       Java_AwSettings_getAllowUniversalAccessFromFileURLsLocked(env, obj);
262
263   web_prefs->allow_file_access_from_file_urls =
264       Java_AwSettings_getAllowFileAccessFromFileURLsLocked(env, obj);
265
266   web_prefs->javascript_can_open_windows_automatically =
267       Java_AwSettings_getJavaScriptCanOpenWindowsAutomaticallyLocked(env, obj);
268
269   web_prefs->supports_multiple_windows =
270       Java_AwSettings_getSupportMultipleWindowsLocked(env, obj);
271
272   web_prefs->plugins_enabled =
273       !Java_AwSettings_getPluginsDisabledLocked(env, obj);
274
275   web_prefs->application_cache_enabled =
276       Java_AwSettings_getAppCacheEnabledLocked(env, obj);
277
278   web_prefs->local_storage_enabled =
279       Java_AwSettings_getDomStorageEnabledLocked(env, obj);
280
281   web_prefs->databases_enabled =
282       Java_AwSettings_getDatabaseEnabledLocked(env, obj);
283
284   web_prefs->wide_viewport_quirk = true;
285   web_prefs->double_tap_to_zoom_enabled = web_prefs->use_wide_viewport =
286       Java_AwSettings_getUseWideViewportLocked(env, obj);
287
288   web_prefs->initialize_at_minimum_page_scale =
289       Java_AwSettings_getLoadWithOverviewModeLocked(env, obj);
290
291   web_prefs->user_gesture_required_for_media_playback =
292       Java_AwSettings_getMediaPlaybackRequiresUserGestureLocked(env, obj);
293
294   ScopedJavaLocalRef<jstring> url =
295       Java_AwSettings_getDefaultVideoPosterURLLocked(env, obj);
296   web_prefs->default_video_poster_url = url.obj() ?
297       GURL(ConvertJavaStringToUTF8(url)) : GURL();
298
299   bool support_quirks = Java_AwSettings_getSupportLegacyQuirksLocked(env, obj);
300   web_prefs->support_deprecated_target_density_dpi = support_quirks;
301   web_prefs->use_legacy_background_size_shorthand_behavior = support_quirks;
302   web_prefs->viewport_meta_layout_size_quirk = support_quirks;
303   web_prefs->viewport_meta_merge_content_quirk = support_quirks;
304   web_prefs->viewport_meta_zero_values_quirk = support_quirks;
305   web_prefs->ignore_main_frame_overflow_hidden_quirk = support_quirks;
306   web_prefs->report_screen_size_in_physical_pixels_quirk = support_quirks;
307
308   web_prefs->password_echo_enabled =
309       Java_AwSettings_getPasswordEchoEnabledLocked(env, obj);
310   web_prefs->spatial_navigation_enabled =
311       Java_AwSettings_getSpatialNavigationLocked(env, obj);
312 }
313
314 static jint Init(JNIEnv* env,
315                  jobject obj,
316                  jint web_contents) {
317   AwSettings* settings = new AwSettings(env, obj, web_contents);
318   return reinterpret_cast<jint>(settings);
319 }
320
321 static jstring GetDefaultUserAgent(JNIEnv* env, jclass clazz) {
322   return base::android::ConvertUTF8ToJavaString(
323       env, content::GetUserAgent(GURL())).Release();
324 }
325
326 bool RegisterAwSettings(JNIEnv* env) {
327   return RegisterNativesImpl(env) >= 0;
328 }
329
330 }  // namespace android_webview