OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chrome/browser/component/web_contents_delegate_android/web_contents_de
legate_android.h" | |
6 | |
7 #include <android/keycodes.h> | |
8 | |
9 #include "base/android/jni_android.h" | |
10 #include "base/android/jni_string.h" | |
11 #include "content/public/browser/android/content_view_core.h" | |
12 #include "content/public/browser/render_widget_host_view.h" | |
13 #include "content/public/browser/invalidate_type.h" | |
14 #include "content/public/browser/page_navigator.h" | |
15 #include "content/public/browser/navigation_controller.h" | |
16 #include "content/public/browser/navigation_entry.h" | |
17 #include "content/public/browser/web_contents.h" | |
18 #include "content/public/common/page_transition_types.h" | |
19 #include "content/public/common/referrer.h" | |
20 #include "jni/WebContentsDelegateAndroid_jni.h" | |
21 #include "ui/gfx/rect.h" | |
22 #include "webkit/glue/window_open_disposition.h" | |
23 | |
24 using base::android::AttachCurrentThread; | |
25 using base::android::ConvertUTF8ToJavaString; | |
26 using base::android::ConvertUTF16ToJavaString; | |
27 using base::android::HasClass; | |
28 using base::android::ScopedJavaLocalRef; | |
29 using content::WebContents; | |
30 | |
31 namespace web_contents_delegate_android { | |
32 | |
33 WebContentsDelegateAndroid::WebContentsDelegateAndroid(JNIEnv* env, jobject obj) | |
34 : weak_java_delegate_(env, obj) { | |
35 } | |
36 | |
37 WebContentsDelegateAndroid::~WebContentsDelegateAndroid() { | |
38 } | |
39 | |
40 ScopedJavaLocalRef<jobject> | |
41 WebContentsDelegateAndroid::GetJavaDelegate(JNIEnv* env) const { | |
42 return weak_java_delegate_.get(env); | |
43 } | |
44 | |
45 // ---------------------------------------------------------------------------- | |
46 // WebContentsDelegate methods | |
47 // ---------------------------------------------------------------------------- | |
48 | |
49 // OpenURLFromTab() will be called when we're performing a browser-intiated | |
50 // navigation. The most common scenario for this is opening new tabs (see | |
51 // RenderViewImpl::decidePolicyForNavigation for more details). | |
52 WebContents* WebContentsDelegateAndroid::OpenURLFromTab( | |
53 WebContents* source, | |
54 const content::OpenURLParams& params) { | |
55 const GURL& url = params.url; | |
56 WindowOpenDisposition disposition = params.disposition; | |
57 content::PageTransition transition( | |
58 PageTransitionFromInt(params.transition)); | |
59 | |
60 if (!source || (disposition != CURRENT_TAB && | |
61 disposition != NEW_FOREGROUND_TAB && | |
62 disposition != NEW_BACKGROUND_TAB && | |
63 disposition != OFF_THE_RECORD)) { | |
64 NOTIMPLEMENTED(); | |
65 return NULL; | |
66 } | |
67 | |
68 JNIEnv* env = AttachCurrentThread(); | |
69 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
70 if (obj.is_null()) | |
71 return WebContentsDelegate::OpenURLFromTab(source, params); | |
72 | |
73 if (disposition == NEW_FOREGROUND_TAB || | |
74 disposition == NEW_BACKGROUND_TAB || | |
75 disposition == OFF_THE_RECORD) { | |
76 JNIEnv* env = AttachCurrentThread(); | |
77 ScopedJavaLocalRef<jstring> java_url = | |
78 ConvertUTF8ToJavaString(env, url.spec()); | |
79 Java_WebContentsDelegateAndroid_openNewTab(env, | |
80 obj.obj(), | |
81 java_url.obj(), | |
82 disposition == OFF_THE_RECORD); | |
83 return NULL; | |
84 } | |
85 | |
86 source->GetController().LoadURL(url, params.referrer, transition, | |
87 std::string()); | |
88 return source; | |
89 } | |
90 | |
91 void WebContentsDelegateAndroid::NavigationStateChanged( | |
92 const WebContents* source, unsigned changed_flags) { | |
93 if (changed_flags & content::INVALIDATE_TYPE_TITLE) { | |
94 JNIEnv* env = AttachCurrentThread(); | |
95 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
96 if (obj.is_null()) | |
97 return; | |
98 Java_WebContentsDelegateAndroid_onTitleUpdated( | |
99 env, obj.obj()); | |
100 } | |
101 } | |
102 | |
103 void WebContentsDelegateAndroid::AddNewContents( | |
104 WebContents* source, | |
105 WebContents* new_contents, | |
106 WindowOpenDisposition disposition, | |
107 const gfx::Rect& initial_pos, | |
108 bool user_gesture, | |
109 bool* was_blocked) { | |
110 JNIEnv* env = AttachCurrentThread(); | |
111 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
112 bool handled = false; | |
113 if (!obj.is_null()) { | |
114 handled = Java_WebContentsDelegateAndroid_addNewContents( | |
115 env, | |
116 obj.obj(), | |
117 reinterpret_cast<jint>(source), | |
118 reinterpret_cast<jint>(new_contents), | |
119 static_cast<jint>(disposition), | |
120 NULL, | |
121 user_gesture); | |
122 } | |
123 if (!handled) | |
124 delete new_contents; | |
125 } | |
126 | |
127 void WebContentsDelegateAndroid::ActivateContents(WebContents* contents) { | |
128 // TODO(dtrainor) When doing the merge I came across this. Should we be | |
129 // activating this tab here? | |
130 } | |
131 | |
132 void WebContentsDelegateAndroid::DeactivateContents(WebContents* contents) { | |
133 // Do nothing. | |
134 } | |
135 | |
136 void WebContentsDelegateAndroid::LoadingStateChanged(WebContents* source) { | |
137 JNIEnv* env = AttachCurrentThread(); | |
138 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
139 if (obj.is_null()) | |
140 return; | |
141 bool has_stopped = source == NULL || !source->IsLoading(); | |
142 | |
143 if (has_stopped) | |
144 Java_WebContentsDelegateAndroid_onLoadStopped(env, obj.obj()); | |
145 else | |
146 Java_WebContentsDelegateAndroid_onLoadStarted(env, obj.obj()); | |
147 } | |
148 | |
149 void WebContentsDelegateAndroid::LoadProgressChanged(WebContents* source, | |
150 double progress) { | |
151 JNIEnv* env = AttachCurrentThread(); | |
152 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
153 if (obj.is_null()) | |
154 return; | |
155 Java_WebContentsDelegateAndroid_onLoadProgressChanged( | |
156 env, | |
157 obj.obj(), | |
158 progress); | |
159 } | |
160 | |
161 void WebContentsDelegateAndroid::CloseContents(WebContents* source) { | |
162 JNIEnv* env = AttachCurrentThread(); | |
163 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
164 if (obj.is_null()) | |
165 return; | |
166 Java_WebContentsDelegateAndroid_closeContents(env, obj.obj()); | |
167 } | |
168 | |
169 void WebContentsDelegateAndroid::MoveContents(WebContents* source, | |
170 const gfx::Rect& pos) { | |
171 // Do nothing. | |
172 } | |
173 | |
174 bool WebContentsDelegateAndroid::AddMessageToConsole( | |
175 WebContents* source, | |
176 int32 level, | |
177 const string16& message, | |
178 int32 line_no, | |
179 const string16& source_id) { | |
180 JNIEnv* env = AttachCurrentThread(); | |
181 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
182 if (obj.is_null()) | |
183 return WebContentsDelegate::AddMessageToConsole(source, level, message, | |
184 line_no, source_id); | |
185 ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(env, message)); | |
186 ScopedJavaLocalRef<jstring> jsource_id( | |
187 ConvertUTF16ToJavaString(env, source_id)); | |
188 int jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_TIP; | |
189 switch (level) { | |
190 case logging::LOG_VERBOSE: | |
191 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_TIP; | |
192 break; | |
193 case logging::LOG_INFO: | |
194 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_LOG; | |
195 break; | |
196 case logging::LOG_WARNING: | |
197 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_WARNING; | |
198 break; | |
199 case logging::LOG_ERROR: | |
200 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_ERROR; | |
201 break; | |
202 default: | |
203 NOTREACHED(); | |
204 } | |
205 return Java_WebContentsDelegateAndroid_addMessageToConsole( | |
206 env, | |
207 GetJavaDelegate(env).obj(), | |
208 jlevel, | |
209 jmessage.obj(), | |
210 line_no, | |
211 jsource_id.obj()); | |
212 } | |
213 | |
214 // TODO(merge): WARNING! method no longer available on the base class. | |
215 // See http://crbug.com/149477 | |
216 void WebContentsDelegateAndroid::URLStarredChanged(WebContents* source, | |
217 bool starred) { | |
218 JNIEnv* env = AttachCurrentThread(); | |
219 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
220 if (obj.is_null()) | |
221 return; | |
222 Java_WebContentsDelegateAndroid_onUrlStarredChanged(env, obj.obj(), starred); | |
223 } | |
224 | |
225 // This is either called from TabContents::DidNavigateMainFramePostCommit() with | |
226 // an empty GURL or responding to RenderViewHost::OnMsgUpateTargetURL(). In | |
227 // Chrome, the latter is not always called, especially not during history | |
228 // navigation. So we only handle the first case and pass the source TabContents' | |
229 // url to Java to update the UI. | |
230 void WebContentsDelegateAndroid::UpdateTargetURL(WebContents* source, | |
231 int32 page_id, | |
232 const GURL& url) { | |
233 if (!url.is_empty()) | |
234 return; | |
235 JNIEnv* env = AttachCurrentThread(); | |
236 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
237 if (obj.is_null()) | |
238 return; | |
239 ScopedJavaLocalRef<jstring> java_url = | |
240 ConvertUTF8ToJavaString(env, source->GetURL().spec()); | |
241 Java_WebContentsDelegateAndroid_onUpdateUrl(env, | |
242 obj.obj(), | |
243 java_url.obj()); | |
244 } | |
245 | |
246 void WebContentsDelegateAndroid::HandleKeyboardEvent( | |
247 content::WebContents* source, | |
248 const content::NativeWebKeyboardEvent& event) { | |
249 jobject key_event = event.os_event; | |
250 if (key_event) { | |
251 JNIEnv* env = AttachCurrentThread(); | |
252 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
253 if (obj.is_null()) | |
254 return; | |
255 Java_WebContentsDelegateAndroid_handleKeyboardEvent( | |
256 env, obj.obj(), key_event); | |
257 } | |
258 } | |
259 | |
260 bool WebContentsDelegateAndroid::TakeFocus(WebContents* source, bool reverse) { | |
261 JNIEnv* env = AttachCurrentThread(); | |
262 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
263 if (obj.is_null()) | |
264 return WebContentsDelegate::TakeFocus(source, reverse); | |
265 return Java_WebContentsDelegateAndroid_takeFocus( | |
266 env, obj.obj(), reverse); | |
267 } | |
268 | |
269 void WebContentsDelegateAndroid::ShowRepostFormWarningDialog( | |
270 WebContents* source) { | |
271 JNIEnv* env = AttachCurrentThread(); | |
272 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
273 if (obj.is_null()) | |
274 return; | |
275 ScopedJavaLocalRef<jobject> content_view_core = | |
276 content::ContentViewCore::FromWebContents(source)->GetJavaObject(); | |
277 if (content_view_core.is_null()) | |
278 return; | |
279 Java_WebContentsDelegateAndroid_showRepostFormWarningDialog(env, obj.obj(), | |
280 content_view_core.obj()); | |
281 } | |
282 | |
283 void WebContentsDelegateAndroid::ToggleFullscreenModeForTab( | |
284 WebContents* web_contents, | |
285 bool enter_fullscreen) { | |
286 JNIEnv* env = AttachCurrentThread(); | |
287 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
288 if (obj.is_null()) | |
289 return; | |
290 Java_WebContentsDelegateAndroid_toggleFullscreenModeForTab( | |
291 env, obj.obj(), enter_fullscreen); | |
292 } | |
293 | |
294 bool WebContentsDelegateAndroid::IsFullscreenForTabOrPending( | |
295 const WebContents* web_contents) const { | |
296 JNIEnv* env = AttachCurrentThread(); | |
297 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env); | |
298 if (obj.is_null()) | |
299 return false; | |
300 return Java_WebContentsDelegateAndroid_isFullscreenForTabOrPending( | |
301 env, obj.obj()); | |
302 } | |
303 | |
304 // ---------------------------------------------------------------------------- | |
305 // Native JNI methods | |
306 // ---------------------------------------------------------------------------- | |
307 | |
308 // Register native methods | |
309 | |
310 bool RegisterWebContentsDelegateAndroid(JNIEnv* env) { | |
311 if (!HasClass(env, kWebContentsDelegateAndroidClassPath)) { | |
312 DLOG(ERROR) << "Unable to find class WebContentsDelegateAndroid!"; | |
313 return false; | |
314 } | |
315 return RegisterNativesImpl(env); | |
316 } | |
317 | |
318 } // namespace web_contents_delegate_android | |
OLD | NEW |