Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: chrome/browser/component/web_contents_delegate_android/web_contents_delegate_android.cc

Issue 10831060: Refactor the Android port to allow access to the chrome layer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: gyp fixes Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/render_widget_host_view.h"
12 #include "content/public/browser/download_item.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 "net/http/http_request_headers.h"
22 #include "ui/gfx/rect.h"
23 #include "webkit/glue/window_open_disposition.h"
24
25 using base::android::AttachCurrentThread;
26 using base::android::CheckException;
27 using base::android::ConvertUTF8ToJavaString;
28 using base::android::ConvertUTF16ToJavaString;
29 using base::android::GetClass;
30 using base::android::GetMethodID;
31 using base::android::HasClass;
32 using base::android::ScopedJavaLocalRef;
33 using content::DownloadItem;
34 using content::JavaScriptDialogCreator;
35 using content::RenderViewHost;
36 using content::WebContents;
37
38 namespace web_contents_delegate_android {
39
40 WebContentsDelegateAndroid::WebContentsDelegateAndroid(JNIEnv* env, jobject obj)
41 : weak_java_delegate_(env, obj),
42 javascript_dialog_creator_(NULL) {
43 }
44
45 WebContentsDelegateAndroid::~WebContentsDelegateAndroid() {
46 }
47
48 ScopedJavaLocalRef<jobject>
49 WebContentsDelegateAndroid::GetJavaDelegate(JNIEnv* env) const {
50 return weak_java_delegate_.get(env);
51 }
52
53 // ----------------------------------------------------------------------------
54 // WebContentsDelegate methods
55 // ----------------------------------------------------------------------------
56
57 // OpenURLFromTab() will be called when we're performing a browser-intiated
58 // navigation. The most common scenario for this is opening new tabs (see
59 // RenderViewImpl::decidePolicyForNavigation for more details).
60 WebContents* WebContentsDelegateAndroid::OpenURLFromTab(
61 WebContents* source,
62 const content::OpenURLParams& params) {
63 const GURL& url = params.url;
64 WindowOpenDisposition disposition = params.disposition;
65 content::PageTransition transition(
66 PageTransitionFromInt(params.transition));
67
68 if (!source || (disposition != CURRENT_TAB &&
69 disposition != NEW_FOREGROUND_TAB &&
70 disposition != NEW_BACKGROUND_TAB &&
71 disposition != OFF_THE_RECORD)) {
72 NOTIMPLEMENTED();
73 return NULL;
74 }
75
76 JNIEnv* env = AttachCurrentThread();
77 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
78 if (obj.is_null())
79 return WebContentsDelegate::OpenURLFromTab(source, params);
80
81 if (disposition == NEW_FOREGROUND_TAB ||
82 disposition == NEW_BACKGROUND_TAB ||
83 disposition == OFF_THE_RECORD) {
84 JNIEnv* env = AttachCurrentThread();
85 ScopedJavaLocalRef<jstring> java_url =
86 ConvertUTF8ToJavaString(env, url.spec());
87 Java_WebContentsDelegateAndroid_openNewTab(env,
88 obj.obj(),
89 java_url.obj(),
90 disposition == OFF_THE_RECORD);
91 return NULL;
92 }
93
94 // TODO(mkosiba): This should be in platform_utils OpenExternal, b/6174564.
95 if (transition == content::PAGE_TRANSITION_LINK && ShouldOverrideLoading(url))
96 return NULL;
97
98 source->GetController().LoadURL(url, params.referrer, transition,
99 std::string());
100 return source;
101 }
102
103 // ShouldIgnoreNavigation will be called for every non-local top level
104 // navigation made by the renderer. If true is returned the renderer will
105 // not perform the navigation. This is done by using synchronous IPC so we
106 // should avoid blocking calls from this method.
107 bool WebContentsDelegateAndroid::ShouldIgnoreNavigation(
108 WebContents* source,
109 const GURL& url,
110 const content::Referrer& referrer,
111 WindowOpenDisposition disposition,
112 content::PageTransition transition_type) {
113
114 // Don't override new tabs.
115 if (disposition == NEW_FOREGROUND_TAB ||
116 disposition == NEW_BACKGROUND_TAB ||
117 disposition == OFF_THE_RECORD)
118 return false;
119
120 return ShouldOverrideLoading(url);
121 }
122
123 void WebContentsDelegateAndroid::NavigationStateChanged(
124 const WebContents* source, unsigned changed_flags) {
125 if (changed_flags & (
126 content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) {
127 JNIEnv* env = AttachCurrentThread();
128 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
129 if (obj.is_null())
130 return;
131 Java_WebContentsDelegateAndroid_onTabHeaderStateChanged(
132 env, obj.obj());
133 }
134 }
135
136 void WebContentsDelegateAndroid::AddNewContents(
137 WebContents* source,
138 WebContents* new_contents,
139 WindowOpenDisposition disposition,
140 const gfx::Rect& initial_pos,
141 bool user_gesture) {
142 JNIEnv* env = AttachCurrentThread();
143 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
144 bool handled = false;
145 if (!obj.is_null()) {
146 handled = Java_WebContentsDelegateAndroid_addNewContents(
147 env,
148 obj.obj(),
149 reinterpret_cast<jint>(source),
150 reinterpret_cast<jint>(new_contents),
151 static_cast<jint>(disposition),
152 NULL,
153 user_gesture);
154 }
155 if (!handled)
156 delete new_contents;
157 }
158
159 void WebContentsDelegateAndroid::ActivateContents(WebContents* contents) {
160 // TODO(dtrainor) When doing the merge I came across this. Should we be
161 // activating this tab here?
162 }
163
164 void WebContentsDelegateAndroid::DeactivateContents(WebContents* contents) {
165 // Do nothing.
166 }
167
168 void WebContentsDelegateAndroid::LoadingStateChanged(WebContents* source) {
169 JNIEnv* env = AttachCurrentThread();
170 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
171 if (obj.is_null())
172 return;
173 bool has_stopped = source == NULL || !source->IsLoading();
174
175 if (has_stopped)
176 Java_WebContentsDelegateAndroid_onLoadStopped(env, obj.obj());
177 else
178 Java_WebContentsDelegateAndroid_onLoadStarted(env, obj.obj());
179 }
180
181 void WebContentsDelegateAndroid::LoadProgressChanged(WebContents* source,
182 double progress) {
183 JNIEnv* env = AttachCurrentThread();
184 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
185 if (obj.is_null())
186 return;
187 Java_WebContentsDelegateAndroid_onLoadProgressChanged(
188 env,
189 obj.obj(),
190 progress);
191 }
192
193 void WebContentsDelegateAndroid::CloseContents(WebContents* source) {
194 JNIEnv* env = AttachCurrentThread();
195 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
196 if (obj.is_null())
197 return;
198 Java_WebContentsDelegateAndroid_closeContents(env, obj.obj());
199 }
200
201 void WebContentsDelegateAndroid::MoveContents(WebContents* source,
202 const gfx::Rect& pos) {
203 // Do nothing.
204 }
205
206 bool WebContentsDelegateAndroid::AddMessageToConsole(
207 WebContents* source,
208 int32 level,
209 const string16& message,
210 int32 line_no,
211 const string16& source_id) {
212 JNIEnv* env = AttachCurrentThread();
213 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
214 if (obj.is_null())
215 return WebContentsDelegate::AddMessageToConsole(source, level, message,
216 line_no, source_id);
217 ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(env, message));
218 ScopedJavaLocalRef<jstring> jsource_id(
219 ConvertUTF16ToJavaString(env, source_id));
220 int jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_TIP;
221 switch (level) {
222 case logging::LOG_VERBOSE:
223 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_TIP;
224 break;
225 case logging::LOG_INFO:
226 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_LOG;
227 break;
228 case logging::LOG_WARNING:
229 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_WARNING;
230 break;
231 case logging::LOG_ERROR:
232 jlevel = WEB_CONTENTS_DELEGATE_LOG_LEVEL_ERROR;
233 break;
234 default:
235 NOTREACHED();
236 }
237 return Java_WebContentsDelegateAndroid_addMessageToConsole(
238 env,
239 GetJavaDelegate(env).obj(),
240 jlevel,
241 jmessage.obj(),
242 line_no,
243 jsource_id.obj());
244 }
245
246 // TODO(merge): WARNING! method no longer available on the base class.
247 // See http://b/issue?id=5862108
248 void WebContentsDelegateAndroid::URLStarredChanged(WebContents* source,
249 bool starred) {
250 JNIEnv* env = AttachCurrentThread();
251 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
252 if (obj.is_null())
253 return;
254 Java_WebContentsDelegateAndroid_onUrlStarredChanged(env, obj.obj(), starred);
255 }
256
257 // This is either called from TabContents::DidNavigateMainFramePostCommit() with
258 // an empty GURL or responding to RenderViewHost::OnMsgUpateTargetURL(). In
259 // Chrome, the latter is not always called, especially not during history
260 // navigation. So we only handle the first case and pass the source TabContents'
261 // url to Java to update the UI.
262 void WebContentsDelegateAndroid::UpdateTargetURL(WebContents* source,
263 int32 page_id,
264 const GURL& url) {
265 if (!url.is_empty())
266 return;
267 JNIEnv* env = AttachCurrentThread();
268 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
269 if (obj.is_null())
270 return;
271 ScopedJavaLocalRef<jstring> java_url =
272 ConvertUTF8ToJavaString(env, source->GetURL().spec());
273 Java_WebContentsDelegateAndroid_onUpdateUrl(env,
274 obj.obj(),
275 java_url.obj());
276 }
277
278 bool WebContentsDelegateAndroid::CanDownload(
279 RenderViewHost* source,
280 int request_id,
281 const std::string& request_method) {
282 if (request_method == net::HttpRequestHeaders::kGetMethod) {
283 // TODO(leandrogracia): re-enable this when calling DownloadController
284 // doesn't introduce a DEPS layering violation.
285 // DownloadController::GetInstance()->CreateGETDownload(
286 // source, request_id);
287 return false;
288 }
289 return true;
290 }
291
292 void WebContentsDelegateAndroid::OnStartDownload(WebContents* source,
293 DownloadItem* download) {
294 // TODO(leandrogracia): re-enable this when calling DownloadController
295 // doesn't introduce a DEPS layering violation.
296 // DownloadController::GetInstance()->OnPostDownloadStarted(
297 // source, download);
298 }
299
300 bool WebContentsDelegateAndroid::ShouldOverrideLoading(const GURL& url) {
301 if (!url.is_valid())
302 return false;
303
304 JNIEnv* env = AttachCurrentThread();
305 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
306 if (obj.is_null())
307 return WebContentsDelegate::ShouldOverrideLoading(url);
308 ScopedJavaLocalRef<jstring> jstring_url =
309 ConvertUTF8ToJavaString(env, url.spec());
310 bool ret = Java_WebContentsDelegateAndroid_shouldOverrideUrlLoading(
311 env, obj.obj(), jstring_url.obj());
312 return ret;
313 }
314
315 void WebContentsDelegateAndroid::HandleKeyboardEvent(
316 content::WebContents* source,
317 const content::NativeWebKeyboardEvent& event) {
318 jobject key_event = event.os_event;
319 if (key_event) {
320 JNIEnv* env = AttachCurrentThread();
321 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
322 if (obj.is_null())
323 return;
324 Java_WebContentsDelegateAndroid_handleKeyboardEvent(
325 env, obj.obj(), key_event);
326 }
327 }
328
329 bool WebContentsDelegateAndroid::TakeFocus(WebContents* source, bool reverse) {
330 JNIEnv* env = AttachCurrentThread();
331 ScopedJavaLocalRef<jobject> obj = GetJavaDelegate(env);
332 if (obj.is_null())
333 return WebContentsDelegate::TakeFocus(source, reverse);
334 return Java_WebContentsDelegateAndroid_takeFocus(
335 env, obj.obj(), reverse);
336 }
337
338 JavaScriptDialogCreator*
339 WebContentsDelegateAndroid::GetJavaScriptDialogCreator() {
340 return javascript_dialog_creator_;
341 }
342
343 // ----------------------------------------------------------------------------
344 // Native JNI methods
345 // ----------------------------------------------------------------------------
346
347 // Register native methods
348
349 bool RegisterWebContentsDelegateAndroid(JNIEnv* env) {
350 if (!HasClass(env, kWebContentsDelegateAndroidClassPath)) {
351 DLOG(ERROR) << "Unable to find class WebContentsDelegateAndroid!";
352 return false;
353 }
354 return RegisterNativesImpl(env);
355 }
356
357 } // namespace web_contents_delegate_android
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698