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

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

Powered by Google App Engine
This is Rietveld 408576698