Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / components / web_contents_delegate_android / web_contents_delegate_android.cc
blob9e6e15e3fb656272f5ae55912be5221f33df51c0
1 // Copyright (c) 2012 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 "components/web_contents_delegate_android/web_contents_delegate_android.h"
7 #include <android/keycodes.h>
9 #include "base/android/jni_android.h"
10 #include "base/android/jni_array.h"
11 #include "base/android/jni_string.h"
12 #include "components/web_contents_delegate_android/color_chooser_android.h"
13 #include "components/web_contents_delegate_android/validation_message_bubble_android.h"
14 #include "content/public/browser/android/content_view_core.h"
15 #include "content/public/browser/color_chooser.h"
16 #include "content/public/browser/global_request_id.h"
17 #include "content/public/browser/invalidate_type.h"
18 #include "content/public/browser/native_web_keyboard_event.h"
19 #include "content/public/browser/navigation_controller.h"
20 #include "content/public/browser/page_navigator.h"
21 #include "content/public/browser/render_widget_host_view.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/common/page_transition_types.h"
24 #include "content/public/common/referrer.h"
25 #include "jni/WebContentsDelegateAndroid_jni.h"
26 #include "ui/base/window_open_disposition.h"
27 #include "ui/gfx/rect.h"
28 #include "url/gurl.h"
30 using base::android::AttachCurrentThread;
31 using base::android::ConvertUTF8ToJavaString;
32 using base::android::ConvertUTF16ToJavaString;
33 using base::android::ScopedJavaLocalRef;
34 using content::ColorChooser;
35 using content::RenderWidgetHostView;
36 using content::WebContents;
37 using content::WebContentsDelegate;
39 namespace web_contents_delegate_android {
41 WebContentsDelegateAndroid::WebContentsDelegateAndroid(JNIEnv* env, jobject obj)
42 : weak_java_delegate_(env, obj) {
45 WebContentsDelegateAndroid::~WebContentsDelegateAndroid() {
48 ScopedJavaLocalRef<jobject>
49 WebContentsDelegateAndroid::GetJavaDelegate(JNIEnv* env) const {
50 return weak_java_delegate_.get(env);
53 // ----------------------------------------------------------------------------
54 // WebContentsDelegate methods
55 // ----------------------------------------------------------------------------
57 ColorChooser* WebContentsDelegateAndroid::OpenColorChooser(
58 WebContents* source,
59 SkColor color,
60 const std::vector<content::ColorSuggestion>& suggestions) {
61 return new ColorChooserAndroid(source, color, suggestions);
64 // OpenURLFromTab() will be called when we're performing a browser-intiated
65 // navigation. The most common scenario for this is opening new tabs (see
66 // RenderViewImpl::decidePolicyForNavigation for more details).
67 WebContents* WebContentsDelegateAndroid::OpenURLFromTab(
68 WebContents* source,
69 const content::OpenURLParams& params) {
70 const GURL& url = params.url;
71 WindowOpenDisposition disposition = params.disposition;
73 if (!source || (disposition != CURRENT_TAB &&
74 disposition != NEW_FOREGROUND_TAB &&
75 disposition != NEW_BACKGROUND_TAB &&
76 disposition != OFF_THE_RECORD)) {
77 NOTIMPLEMENTED();
78 return NULL;
81 JNIEnv* env = AttachCurrentThread();
82 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
83 if (obj.is_null())
84 return WebContentsDelegate::OpenURLFromTab(source, params);
86 if (disposition == NEW_FOREGROUND_TAB ||
87 disposition == NEW_BACKGROUND_TAB ||
88 disposition == OFF_THE_RECORD) {
89 JNIEnv* env = AttachCurrentThread();
90 ScopedJavaLocalRef<jstring> java_url =
91 ConvertUTF8ToJavaString(env, url.spec());
92 ScopedJavaLocalRef<jstring> extra_headers =
93 ConvertUTF8ToJavaString(env, params.extra_headers);
94 ScopedJavaLocalRef<jbyteArray> post_data;
95 if (params.uses_post &&
96 params.browser_initiated_post_data.get() &&
97 params.browser_initiated_post_data.get()->size()) {
98 post_data = base::android::ToJavaByteArray(
99 env,
100 params.browser_initiated_post_data.get()->front_as<uint8>(),
101 params.browser_initiated_post_data.get()->size());
103 Java_WebContentsDelegateAndroid_openNewTab(env,
104 obj.obj(),
105 java_url.obj(),
106 extra_headers.obj(),
107 post_data.obj(),
108 disposition,
109 params.is_renderer_initiated);
110 return NULL;
113 // content::OpenURLParams -> content::NavigationController::LoadURLParams
114 content::NavigationController::LoadURLParams load_params(url);
115 load_params.referrer = params.referrer;
116 load_params.frame_tree_node_id = params.frame_tree_node_id;
117 load_params.redirect_chain = params.redirect_chain;
118 load_params.transition_type = params.transition;
119 load_params.extra_headers = params.extra_headers;
120 load_params.should_replace_current_entry =
121 params.should_replace_current_entry;
122 load_params.is_renderer_initiated = params.is_renderer_initiated;
124 if (params.transferred_global_request_id != content::GlobalRequestID()) {
125 load_params.transferred_global_request_id =
126 params.transferred_global_request_id;
129 // Only allows the browser-initiated navigation to use POST.
130 if (params.uses_post && !params.is_renderer_initiated) {
131 load_params.load_type =
132 content::NavigationController::LOAD_TYPE_BROWSER_INITIATED_HTTP_POST;
133 load_params.browser_initiated_post_data =
134 params.browser_initiated_post_data;
137 source->GetController().LoadURLWithParams(load_params);
139 return source;
142 void WebContentsDelegateAndroid::NavigationStateChanged(
143 const WebContents* source, content::InvalidateTypes changed_flags) {
144 JNIEnv* env = AttachCurrentThread();
145 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
146 if (obj.is_null())
147 return;
148 Java_WebContentsDelegateAndroid_navigationStateChanged(
149 env,
150 obj.obj(),
151 changed_flags);
154 void WebContentsDelegateAndroid::VisibleSSLStateChanged(
155 const WebContents* source) {
156 JNIEnv* env = AttachCurrentThread();
157 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
158 if (obj.is_null())
159 return;
160 Java_WebContentsDelegateAndroid_visibleSSLStateChanged(
161 env,
162 obj.obj());
165 void WebContentsDelegateAndroid::ActivateContents(WebContents* contents) {
166 JNIEnv* env = AttachCurrentThread();
167 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
168 if (obj.is_null())
169 return;
170 Java_WebContentsDelegateAndroid_activateContents(env, obj.obj());
173 void WebContentsDelegateAndroid::DeactivateContents(WebContents* contents) {
174 // On desktop the current window is deactivated here, bringing the next window
175 // to focus. Not implemented on Android.
178 void WebContentsDelegateAndroid::LoadingStateChanged(WebContents* source,
179 bool to_different_document) {
180 JNIEnv* env = AttachCurrentThread();
181 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
182 if (obj.is_null())
183 return;
184 bool has_stopped = source == NULL || !source->IsLoading();
186 if (has_stopped)
187 Java_WebContentsDelegateAndroid_onLoadStopped(env, obj.obj());
188 else
189 Java_WebContentsDelegateAndroid_onLoadStarted(env, obj.obj());
192 void WebContentsDelegateAndroid::LoadProgressChanged(WebContents* source,
193 double progress) {
194 JNIEnv* env = AttachCurrentThread();
195 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
196 if (obj.is_null())
197 return;
198 Java_WebContentsDelegateAndroid_notifyLoadProgressChanged(
199 env,
200 obj.obj(),
201 progress);
204 void WebContentsDelegateAndroid::RendererUnresponsive(WebContents* source) {
205 JNIEnv* env = AttachCurrentThread();
206 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
207 if (obj.is_null())
208 return;
209 Java_WebContentsDelegateAndroid_rendererUnresponsive(env, obj.obj());
212 void WebContentsDelegateAndroid::RendererResponsive(WebContents* source) {
213 JNIEnv* env = AttachCurrentThread();
214 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
215 if (obj.is_null())
216 return;
217 Java_WebContentsDelegateAndroid_rendererResponsive(env, obj.obj());
220 void WebContentsDelegateAndroid::CloseContents(WebContents* source) {
221 JNIEnv* env = AttachCurrentThread();
222 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
223 if (obj.is_null())
224 return;
225 Java_WebContentsDelegateAndroid_closeContents(env, obj.obj());
228 void WebContentsDelegateAndroid::MoveContents(WebContents* source,
229 const gfx::Rect& pos) {
230 // Do nothing.
233 bool WebContentsDelegateAndroid::AddMessageToConsole(
234 WebContents* source,
235 int32 level,
236 const base::string16& message,
237 int32 line_no,
238 const base::string16& source_id) {
239 JNIEnv* env = AttachCurrentThread();
240 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
241 if (obj.is_null())
242 return WebContentsDelegate::AddMessageToConsole(source, level, message,
243 line_no, source_id);
244 ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(env, message));
245 ScopedJavaLocalRef<jstring> jsource_id(
246 ConvertUTF16ToJavaString(env, source_id));
247 int jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_DEBUG;
248 switch (level) {
249 case logging::LOG_VERBOSE:
250 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_DEBUG;
251 break;
252 case logging::LOG_INFO:
253 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_LOG;
254 break;
255 case logging::LOG_WARNING:
256 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_WARNING;
257 break;
258 case logging::LOG_ERROR:
259 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_ERROR;
260 break;
261 default:
262 NOTREACHED();
264 return Java_WebContentsDelegateAndroid_addMessageToConsole(
265 env,
266 GetJavaDelegate(env).obj(),
267 jlevel,
268 jmessage.obj(),
269 line_no,
270 jsource_id.obj());
273 // This is either called from TabContents::DidNavigateMainFramePostCommit() with
274 // an empty GURL or responding to RenderViewHost::OnMsgUpateTargetURL(). In
275 // Chrome, the latter is not always called, especially not during history
276 // navigation. So we only handle the first case and pass the source TabContents'
277 // url to Java to update the UI.
278 void WebContentsDelegateAndroid::UpdateTargetURL(WebContents* source,
279 int32 page_id,
280 const GURL& url) {
281 if (!url.is_empty())
282 return;
283 JNIEnv* env = AttachCurrentThread();
284 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
285 if (obj.is_null())
286 return;
287 ScopedJavaLocalRef<jstring> java_url =
288 ConvertUTF8ToJavaString(env, source->GetURL().spec());
289 Java_WebContentsDelegateAndroid_onUpdateUrl(env,
290 obj.obj(),
291 java_url.obj());
294 void WebContentsDelegateAndroid::HandleKeyboardEvent(
295 WebContents* source,
296 const content::NativeWebKeyboardEvent& event) {
297 jobject key_event = event.os_event;
298 if (key_event) {
299 JNIEnv* env = AttachCurrentThread();
300 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
301 if (obj.is_null())
302 return;
303 Java_WebContentsDelegateAndroid_handleKeyboardEvent(
304 env, obj.obj(), key_event);
308 bool WebContentsDelegateAndroid::TakeFocus(WebContents* source, bool reverse) {
309 JNIEnv* env = AttachCurrentThread();
310 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
311 if (obj.is_null())
312 return WebContentsDelegate::TakeFocus(source, reverse);
313 return Java_WebContentsDelegateAndroid_takeFocus(
314 env, obj.obj(), reverse);
317 void WebContentsDelegateAndroid::ShowRepostFormWarningDialog(
318 WebContents* source) {
319 JNIEnv* env = AttachCurrentThread();
320 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
321 if (obj.is_null())
322 return;
323 ScopedJavaLocalRef<jobject> content_view_core =
324 content::ContentViewCore::FromWebContents(source)->GetJavaObject();
325 if (content_view_core.is_null())
326 return;
327 Java_WebContentsDelegateAndroid_showRepostFormWarningDialog(env, obj.obj(),
328 content_view_core.obj());
331 void WebContentsDelegateAndroid::ToggleFullscreenModeForTab(
332 WebContents* web_contents,
333 bool enter_fullscreen) {
334 JNIEnv* env = AttachCurrentThread();
335 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
336 if (obj.is_null())
337 return;
338 Java_WebContentsDelegateAndroid_toggleFullscreenModeForTab(
339 env, obj.obj(), enter_fullscreen);
342 bool WebContentsDelegateAndroid::IsFullscreenForTabOrPending(
343 const WebContents* web_contents) const {
344 JNIEnv* env = AttachCurrentThread();
345 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
346 if (obj.is_null())
347 return false;
348 return Java_WebContentsDelegateAndroid_isFullscreenForTabOrPending(
349 env, obj.obj());
352 void WebContentsDelegateAndroid::ShowValidationMessage(
353 WebContents* web_contents,
354 const gfx::Rect& anchor_in_root_view,
355 const base::string16& main_text,
356 const base::string16& sub_text) {
357 RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
358 if (rwhv) {
359 validation_message_bubble_.reset(
360 new ValidationMessageBubbleAndroid(rwhv->GetRenderWidgetHost(),
361 anchor_in_root_view,
362 main_text,
363 sub_text));
367 void WebContentsDelegateAndroid::HideValidationMessage(
368 WebContents* web_contents) {
369 validation_message_bubble_.reset();
372 void WebContentsDelegateAndroid::MoveValidationMessage(
373 WebContents* web_contents,
374 const gfx::Rect& anchor_in_root_view) {
375 if (!validation_message_bubble_)
376 return;
377 RenderWidgetHostView* rwhv = web_contents->GetRenderWidgetHostView();
378 if (rwhv) {
379 validation_message_bubble_->SetPositionRelativeToAnchor(
380 rwhv->GetRenderWidgetHost(), anchor_in_root_view);
383 // ----------------------------------------------------------------------------
384 // Native JNI methods
385 // ----------------------------------------------------------------------------
387 // Register native methods
389 bool RegisterWebContentsDelegateAndroid(JNIEnv* env) {
390 return RegisterNativesImpl(env);
393 } // namespace web_contents_delegate_android