cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / components / web_contents_delegate_android / web_contents_delegate_android.cc
blobc908f6a61a9038e0d599c98dd4fbafb83664ed38
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 "content/public/browser/android/content_view_core.h"
14 #include "content/public/browser/color_chooser.h"
15 #include "content/public/browser/invalidate_type.h"
16 #include "content/public/browser/native_web_keyboard_event.h"
17 #include "content/public/browser/page_navigator.h"
18 #include "content/public/browser/render_widget_host_view.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/common/page_transition_types.h"
21 #include "content/public/common/referrer.h"
22 #include "jni/WebContentsDelegateAndroid_jni.h"
23 #include "ui/base/window_open_disposition.h"
24 #include "ui/gfx/rect.h"
25 #include "url/gurl.h"
27 using base::android::AttachCurrentThread;
28 using base::android::ConvertUTF8ToJavaString;
29 using base::android::ConvertUTF16ToJavaString;
30 using base::android::HasClass;
31 using base::android::ScopedJavaLocalRef;
32 using content::ColorChooser;
33 using content::WebContents;
34 using content::WebContentsDelegate;
36 namespace web_contents_delegate_android {
38 WebContentsDelegateAndroid::WebContentsDelegateAndroid(JNIEnv* env, jobject obj)
39 : weak_java_delegate_(env, obj) {
42 WebContentsDelegateAndroid::~WebContentsDelegateAndroid() {
45 ScopedJavaLocalRef<jobject>
46 WebContentsDelegateAndroid::GetJavaDelegate(JNIEnv* env) const {
47 return weak_java_delegate_.get(env);
50 // ----------------------------------------------------------------------------
51 // WebContentsDelegate methods
52 // ----------------------------------------------------------------------------
54 ColorChooser* WebContentsDelegateAndroid::OpenColorChooser(WebContents* source,
55 SkColor color) {
56 return new ColorChooserAndroid(source, color);
59 // OpenURLFromTab() will be called when we're performing a browser-intiated
60 // navigation. The most common scenario for this is opening new tabs (see
61 // RenderViewImpl::decidePolicyForNavigation for more details).
62 WebContents* WebContentsDelegateAndroid::OpenURLFromTab(
63 WebContents* source,
64 const content::OpenURLParams& params) {
65 const GURL& url = params.url;
66 WindowOpenDisposition disposition = params.disposition;
67 content::PageTransition transition(
68 PageTransitionFromInt(params.transition));
70 if (!source || (disposition != CURRENT_TAB &&
71 disposition != NEW_FOREGROUND_TAB &&
72 disposition != NEW_BACKGROUND_TAB &&
73 disposition != OFF_THE_RECORD)) {
74 NOTIMPLEMENTED();
75 return NULL;
78 JNIEnv* env = AttachCurrentThread();
79 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
80 if (obj.is_null())
81 return WebContentsDelegate::OpenURLFromTab(source, params);
83 if (disposition == NEW_FOREGROUND_TAB ||
84 disposition == NEW_BACKGROUND_TAB ||
85 disposition == OFF_THE_RECORD) {
86 JNIEnv* env = AttachCurrentThread();
87 ScopedJavaLocalRef<jstring> java_url =
88 ConvertUTF8ToJavaString(env, url.spec());
89 ScopedJavaLocalRef<jstring> extra_headers =
90 ConvertUTF8ToJavaString(env, params.extra_headers);
91 ScopedJavaLocalRef<jbyteArray> post_data;
92 if (params.uses_post &&
93 params.browser_initiated_post_data.get() &&
94 params.browser_initiated_post_data.get()->size()) {
95 post_data = base::android::ToJavaByteArray(
96 env,
97 reinterpret_cast<const uint8*>(
98 params.browser_initiated_post_data.get()->front()),
99 params.browser_initiated_post_data.get()->size());
101 Java_WebContentsDelegateAndroid_openNewTab(env,
102 obj.obj(),
103 java_url.obj(),
104 extra_headers.obj(),
105 post_data.obj(),
106 disposition);
107 return NULL;
110 source->GetController().LoadURL(url, params.referrer, transition,
111 std::string());
112 return source;
115 void WebContentsDelegateAndroid::NavigationStateChanged(
116 const WebContents* source, unsigned changed_flags) {
117 JNIEnv* env = AttachCurrentThread();
118 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
119 if (obj.is_null())
120 return;
121 Java_WebContentsDelegateAndroid_navigationStateChanged(
122 env,
123 obj.obj(),
124 changed_flags);
127 void WebContentsDelegateAndroid::ActivateContents(WebContents* contents) {
128 JNIEnv* env = AttachCurrentThread();
129 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
130 if (obj.is_null())
131 return;
132 Java_WebContentsDelegateAndroid_activateContents(env, obj.obj());
135 void WebContentsDelegateAndroid::DeactivateContents(WebContents* contents) {
136 // On desktop the current window is deactivated here, bringing the next window
137 // to focus. Not implemented on Android.
140 void WebContentsDelegateAndroid::LoadingStateChanged(WebContents* source) {
141 JNIEnv* env = AttachCurrentThread();
142 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
143 if (obj.is_null())
144 return;
145 bool has_stopped = source == NULL || !source->IsLoading();
147 if (has_stopped)
148 Java_WebContentsDelegateAndroid_onLoadStopped(env, obj.obj());
149 else
150 Java_WebContentsDelegateAndroid_onLoadStarted(env, obj.obj());
153 void WebContentsDelegateAndroid::LoadProgressChanged(WebContents* source,
154 double progress) {
155 JNIEnv* env = AttachCurrentThread();
156 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
157 if (obj.is_null())
158 return;
159 Java_WebContentsDelegateAndroid_notifyLoadProgressChanged(
160 env,
161 obj.obj(),
162 progress);
165 void WebContentsDelegateAndroid::RendererUnresponsive(WebContents* source) {
166 JNIEnv* env = AttachCurrentThread();
167 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
168 if (obj.is_null())
169 return;
170 Java_WebContentsDelegateAndroid_rendererUnresponsive(env, obj.obj());
173 void WebContentsDelegateAndroid::RendererResponsive(WebContents* source) {
174 JNIEnv* env = AttachCurrentThread();
175 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
176 if (obj.is_null())
177 return;
178 Java_WebContentsDelegateAndroid_rendererResponsive(env, obj.obj());
181 void WebContentsDelegateAndroid::CloseContents(WebContents* source) {
182 JNIEnv* env = AttachCurrentThread();
183 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
184 if (obj.is_null())
185 return;
186 Java_WebContentsDelegateAndroid_closeContents(env, obj.obj());
189 void WebContentsDelegateAndroid::MoveContents(WebContents* source,
190 const gfx::Rect& pos) {
191 // Do nothing.
194 bool WebContentsDelegateAndroid::AddMessageToConsole(
195 WebContents* source,
196 int32 level,
197 const base::string16& message,
198 int32 line_no,
199 const base::string16& source_id) {
200 JNIEnv* env = AttachCurrentThread();
201 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
202 if (obj.is_null())
203 return WebContentsDelegate::AddMessageToConsole(source, level, message,
204 line_no, source_id);
205 ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(env, message));
206 ScopedJavaLocalRef<jstring> jsource_id(
207 ConvertUTF16ToJavaString(env, source_id));
208 int jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_DEBUG;
209 switch (level) {
210 case logging::LOG_VERBOSE:
211 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_DEBUG;
212 break;
213 case logging::LOG_INFO:
214 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_LOG;
215 break;
216 case logging::LOG_WARNING:
217 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_WARNING;
218 break;
219 case logging::LOG_ERROR:
220 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_ERROR;
221 break;
222 default:
223 NOTREACHED();
225 return Java_WebContentsDelegateAndroid_addMessageToConsole(
226 env,
227 GetJavaDelegate(env).obj(),
228 jlevel,
229 jmessage.obj(),
230 line_no,
231 jsource_id.obj());
234 // This is either called from TabContents::DidNavigateMainFramePostCommit() with
235 // an empty GURL or responding to RenderViewHost::OnMsgUpateTargetURL(). In
236 // Chrome, the latter is not always called, especially not during history
237 // navigation. So we only handle the first case and pass the source TabContents'
238 // url to Java to update the UI.
239 void WebContentsDelegateAndroid::UpdateTargetURL(WebContents* source,
240 int32 page_id,
241 const GURL& url) {
242 if (!url.is_empty())
243 return;
244 JNIEnv* env = AttachCurrentThread();
245 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
246 if (obj.is_null())
247 return;
248 ScopedJavaLocalRef<jstring> java_url =
249 ConvertUTF8ToJavaString(env, source->GetURL().spec());
250 Java_WebContentsDelegateAndroid_onUpdateUrl(env,
251 obj.obj(),
252 java_url.obj());
255 void WebContentsDelegateAndroid::HandleKeyboardEvent(
256 WebContents* source,
257 const content::NativeWebKeyboardEvent& event) {
258 jobject key_event = event.os_event;
259 if (key_event) {
260 JNIEnv* env = AttachCurrentThread();
261 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
262 if (obj.is_null())
263 return;
264 Java_WebContentsDelegateAndroid_handleKeyboardEvent(
265 env, obj.obj(), key_event);
269 bool WebContentsDelegateAndroid::TakeFocus(WebContents* source, bool reverse) {
270 JNIEnv* env = AttachCurrentThread();
271 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
272 if (obj.is_null())
273 return WebContentsDelegate::TakeFocus(source, reverse);
274 return Java_WebContentsDelegateAndroid_takeFocus(
275 env, obj.obj(), reverse);
278 void WebContentsDelegateAndroid::ShowRepostFormWarningDialog(
279 WebContents* source) {
280 JNIEnv* env = AttachCurrentThread();
281 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
282 if (obj.is_null())
283 return;
284 ScopedJavaLocalRef<jobject> content_view_core =
285 content::ContentViewCore::FromWebContents(source)->GetJavaObject();
286 if (content_view_core.is_null())
287 return;
288 Java_WebContentsDelegateAndroid_showRepostFormWarningDialog(env, obj.obj(),
289 content_view_core.obj());
292 void WebContentsDelegateAndroid::ToggleFullscreenModeForTab(
293 WebContents* web_contents,
294 bool enter_fullscreen) {
295 JNIEnv* env = AttachCurrentThread();
296 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
297 if (obj.is_null())
298 return;
299 Java_WebContentsDelegateAndroid_toggleFullscreenModeForTab(
300 env, obj.obj(), enter_fullscreen);
303 bool WebContentsDelegateAndroid::IsFullscreenForTabOrPending(
304 const WebContents* web_contents) const {
305 JNIEnv* env = AttachCurrentThread();
306 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
307 if (obj.is_null())
308 return false;
309 return Java_WebContentsDelegateAndroid_isFullscreenForTabOrPending(
310 env, obj.obj());
313 void WebContentsDelegateAndroid::DidProgrammaticallyScroll(
314 WebContents* web_contents, const gfx::Vector2d& scroll_point) {
315 JNIEnv* env = AttachCurrentThread();
316 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
317 if (obj.is_null())
318 return;
319 Java_WebContentsDelegateAndroid_didProgrammaticallyScroll(
320 env, obj.obj(), scroll_point.x(), scroll_point.y());
323 // ----------------------------------------------------------------------------
324 // Native JNI methods
325 // ----------------------------------------------------------------------------
327 // Register native methods
329 bool RegisterWebContentsDelegateAndroid(JNIEnv* env) {
330 if (!HasClass(env, kWebContentsDelegateAndroidClassPath)) {
331 DLOG(ERROR) << "Unable to find class WebContentsDelegateAndroid!";
332 return false;
334 return RegisterNativesImpl(env);
337 } // namespace web_contents_delegate_android