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

Side by Side Diff: content/browser/android/content_view_client.cc

Issue 10536066: android content shell bringup. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 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) 2010 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 "content/browser/android/content_view_client.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/browser/android/content_util.h"
12 #include "content/public/browser/content_view.h"
13 #include "content/browser/android/download_controller.h"
14 #include "content/browser/renderer_host/render_view_host_impl.h"
15 #include "content/public/browser/render_widget_host_view.h"
16 #include "content/public/browser/download_item.h"
17 #include "content/public/browser/invalidate_type.h"
18 #include "content/public/browser/page_navigator.h"
19 #include "content/public/browser/navigation_controller.h"
20 #include "content/public/browser/navigation_entry.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/common/find_match_rect_android.h"
23 #include "content/public/common/page_transition_types.h"
24 #include "content/public/common/referrer.h"
25 #include "jni/content_view_client_jni.h"
26 #include "net/http/http_request_headers.h"
27 #include "ui/gfx/rect.h"
28 #include "webkit/glue/window_open_disposition.h"
29
30 using base::android::AttachCurrentThread;
31 using base::android::CheckException;
32 using base::android::ConvertUTF8ToJavaString;
33 using base::android::ConvertUTF16ToJavaString;
34 using base::android::GetClass;
35 using base::android::GetMethodID;
36 using base::android::HasClass;
37 using base::android::ScopedJavaLocalRef;
38 using content::DownloadItem;
39 using content::RenderViewHost;
40 using content::WebContents;
41
42 using namespace net;
43
44 namespace content {
45
46 ContentViewClient::ContentViewClient(JNIEnv* env, jobject obj)
47 : weak_java_client_(env, obj),
48 find_helper_(NULL),
49 javascript_dialog_creator_(NULL) {
50 }
51
52 ContentViewClient::~ContentViewClient() {
53 }
54
55 // static
56 ContentViewClient* ContentViewClient::CreateNativeContentViewClient(
57 JNIEnv* env, jobject obj) {
58 if (!obj)
59 return NULL;
60
61 return new ContentViewClient(env, obj);
62 }
63
64 void ContentViewClient::OnInternalPageLoadRequest(
65 content::WebContents* source, const GURL& url) {
66 last_requested_navigation_url_ = url;
67 }
68
69
70 void ContentViewClient::OnPageStarted(const GURL& url) {
71 JNIEnv* env = AttachCurrentThread();
72 ScopedJavaLocalRef<jstring> jstring_url =
73 ConvertUTF8ToJavaString(env, url.spec());
74 Java_ContentViewClient_onPageStarted(env, weak_java_client_.get(env).obj(),
75 jstring_url.obj());
76 }
77
78 void ContentViewClient::OnPageFinished(const GURL& url) {
79 if (url == last_requested_navigation_url_)
80 last_requested_navigation_url_ = GURL::EmptyGURL();
81
82 JNIEnv* env = AttachCurrentThread();
83 ScopedJavaLocalRef<jstring> jstring_url =
84 ConvertUTF8ToJavaString(env, url.spec());
85
86 Java_ContentViewClient_onPageFinished(env, weak_java_client_.get(env).obj(),
87 jstring_url.obj());
88 CheckException(env);
89 }
90
91 void ContentViewClient::OnReceivedError(int error_code,
92 const string16& description,
93 const GURL& url) {
94 JNIEnv* env = AttachCurrentThread();
95 ScopedJavaLocalRef<jstring> jstring_error_description =
96 ConvertUTF8ToJavaString(env, url.spec());
97 ScopedJavaLocalRef<jstring> jstring_url =
98 ConvertUTF8ToJavaString(env, url.spec());
99
100 Java_ContentViewClient_onReceivedError(
101 env, weak_java_client_.get(env).obj(),
102 ToContentViewClientError(error_code),
103 jstring_error_description.obj(), jstring_url.obj());
104 }
105
106 void ContentViewClient::OnReceivedHttpAuthRequest(
107 jobject auth_handler,
108 const string16& host,
109 const string16& realm) {
110 /* TODO(jrg): upstream this once ContentHttpAuthHandler.java is
111 upstreamed, and onReceivedHttpAuthRequest() is upstreamed in
112 ContentViewClient.java */
113 NOTREACHED();
114 }
115
116 void ContentViewClient::OnDidCommitMainFrame(const GURL& url,
117 const GURL& base_url) {
118 JNIEnv* env = AttachCurrentThread();
119 ScopedJavaLocalRef<jstring> jstring_url =
120 ConvertUTF8ToJavaString(env, url.spec());
121 ScopedJavaLocalRef<jstring> jstring_base_url =
122 ConvertUTF8ToJavaString(env, base_url.spec());
123
124 Java_ContentViewClient_onMainFrameCommitted(
125 env, weak_java_client_.get(env).obj(),
126 jstring_url.obj(), jstring_base_url.obj());
127 }
128
129 void ContentViewClient::OnInterstitialShown() {
130 JNIEnv* env = AttachCurrentThread();
131 Java_ContentViewClient_onInterstitialShown(
132 env, weak_java_client_.get(env).obj());
133 }
134
135 void ContentViewClient::OnInterstitialHidden() {
136 JNIEnv* env = AttachCurrentThread();
137 Java_ContentViewClient_onInterstitialHidden(
138 env, weak_java_client_.get(env).obj());
139 }
140
141 void ContentViewClient::SetFindHelper(FindHelper* find_helper) {
142 find_helper_ = find_helper;
143 }
144
145 void ContentViewClient::SetJavaScriptDialogCreator(
146 content::JavaScriptDialogCreator* javascript_dialog_creator) {
147 javascript_dialog_creator_ = javascript_dialog_creator;
148 }
149
150 bool ContentViewClient::OnJSModalDialog(content::JavaScriptMessageType type,
151 bool is_before_unload_dialog,
152 const GURL& url,
153 const string16& message,
154 const string16& default_value) {
155 JNIEnv* env = AttachCurrentThread();
156 ScopedJavaLocalRef<jstring> jurl(ConvertUTF8ToJavaString(env, url.spec()));
157 ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(env, message));
158
159 // Special case for beforeunload dialogs, as that isn't encoded in the
160 // |type| of the dialog.
161 if (is_before_unload_dialog) {
162 return Java_ContentViewClient_onJsBeforeUnload(env,
163 weak_java_client_.get(env).obj(),
164 jurl.obj(),
165 jmessage.obj());
166 }
167
168 switch (type) {
169 case content::JAVASCRIPT_MESSAGE_TYPE_ALERT:
170 return Java_ContentViewClient_onJsAlert(env,
171 weak_java_client_.get(env).obj(),
172 jurl.obj(),
173 jmessage.obj());
174
175 case content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM:
176 return Java_ContentViewClient_onJsConfirm(env,
177 weak_java_client_.get(env).obj(),
178 jurl.obj(),
179 jmessage.obj());
180
181 case content::JAVASCRIPT_MESSAGE_TYPE_PROMPT: {
182 ScopedJavaLocalRef<jstring> jdefault_value(
183 ConvertUTF16ToJavaString(env, default_value));
184 return Java_ContentViewClient_onJsPrompt(env,
185 weak_java_client_.get(env).obj(),
186 jurl.obj(),
187 jmessage.obj(),
188 jdefault_value.obj());
189 }
190
191 default:
192 NOTREACHED();
193 return false;
194 }
195 }
196
197 // ----------------------------------------------------------------------------
198 // WebContentsDelegate methods
199 // ----------------------------------------------------------------------------
200
201 // OpenURLFromTab() will be called when we're performing a browser-intiated
202 // navigation. The most common scenario for this is opening new tabs (see
203 // RenderViewImpl::decidePolicyForNavigation for more details).
204 WebContents* ContentViewClient::OpenURLFromTab(
205 WebContents* source,
206 const content::OpenURLParams& params) {
207 const GURL& url = params.url;
208 WindowOpenDisposition disposition = params.disposition;
209 content::PageTransition transition(
210 content::PageTransitionFromInt(params.transition));
211
212 if (!source || (disposition != CURRENT_TAB &&
213 disposition != NEW_FOREGROUND_TAB &&
214 disposition != NEW_BACKGROUND_TAB &&
215 disposition != OFF_THE_RECORD)) {
216 NOTIMPLEMENTED();
217 return NULL;
218 }
219
220 if (disposition == NEW_FOREGROUND_TAB ||
221 disposition == NEW_BACKGROUND_TAB ||
222 disposition == OFF_THE_RECORD) {
223 JNIEnv* env = AttachCurrentThread();
224 ScopedJavaLocalRef<jstring> java_url =
225 ConvertUTF8ToJavaString(env, url.spec());
226 Java_ContentViewClient_openNewTab(env,
227 weak_java_client_.get(env).obj(),
228 java_url.obj(),
229 disposition == OFF_THE_RECORD);
230 return NULL;
231 }
232
233 // TODO(mkosiba): This should be in platform_utils OpenExternal, b/6174564.
234 if (transition == content::PAGE_TRANSITION_LINK &&
235 ShouldOverrideLoading(url))
236 return NULL;
237
238 source->GetController().LoadURL(url, params.referrer, transition,
239 std::string());
240 return source;
241 }
242
243 // ShouldIgnoreNavigation will be called for every non-local top level
244 // navigation made by the renderer. If true is returned the renderer will
245 // not perform the navigation. This is done by using synchronous IPC so we
246 // should avoid blocking calls from this method.
247 bool ContentViewClient::ShouldIgnoreNavigation(
248 WebContents* source,
249 const GURL& url,
250 const content::Referrer& referrer,
251 WindowOpenDisposition disposition,
252 content::PageTransition transition_type) {
253
254 // Don't override new tabs.
255 if (disposition == NEW_FOREGROUND_TAB ||
256 disposition == NEW_BACKGROUND_TAB ||
257 disposition == OFF_THE_RECORD)
258 return false;
259
260 // Don't override the navigation that has just been requested via the
261 // ContentView.loadUrl method.
262 if (url == last_requested_navigation_url_) {
263 last_requested_navigation_url_ = GURL::EmptyGURL();
264 return false;
265 }
266
267 return ShouldOverrideLoading(url);
268 }
269
270 void ContentViewClient::NavigationStateChanged(
271 const WebContents* source, unsigned changed_flags) {
272 if (changed_flags & (
273 content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) {
274 JNIEnv* env = AttachCurrentThread();
275 Java_ContentViewClient_onTabHeaderStateChanged(
276 env, weak_java_client_.get(env).obj());
277 }
278 }
279
280 void ContentViewClient::AddNewContents(WebContents* source,
281 WebContents* new_contents,
282 WindowOpenDisposition disposition,
283 const gfx::Rect& initial_pos,
284 bool user_gesture) {
285 JNIEnv* env = AttachCurrentThread();
286 bool handled = Java_ContentViewClient_addNewContents(
287 env,
288 weak_java_client_.get(env).obj(),
289 reinterpret_cast<jint>(source),
290 reinterpret_cast<jint>(new_contents),
291 static_cast<jint>(disposition),
292 NULL,
293 user_gesture);
294 if (!handled)
295 delete new_contents;
296 }
297
298 void ContentViewClient::ActivateContents(WebContents* contents) {
299 // TODO(dtrainor) When doing the merge I came across this. Should we be
300 // activating this tab here?
301 }
302
303 void ContentViewClient::DeactivateContents(WebContents* contents) {
304 // Do nothing.
305 }
306
307 void ContentViewClient::LoadingStateChanged(WebContents* source) {
308 JNIEnv* env = AttachCurrentThread();
309 bool has_stopped = source == NULL || !source->IsLoading();
310
311 if (has_stopped)
312 Java_ContentViewClient_onLoadStopped(
313 env, weak_java_client_.get(env).obj());
314 else
315 Java_ContentViewClient_onLoadStarted(
316 env, weak_java_client_.get(env).obj());
317 }
318
319 void ContentViewClient::LoadProgressChanged(double progress) {
320 JNIEnv* env = AttachCurrentThread();
321 Java_ContentViewClient_onLoadProgressChanged(
322 env,
323 weak_java_client_.get(env).obj(),
324 progress);
325 }
326
327 void ContentViewClient::CloseContents(WebContents* source) {
328 JNIEnv* env = AttachCurrentThread();
329 Java_ContentViewClient_closeContents(env, weak_java_client_.get(env).obj());
330 }
331
332 void ContentViewClient::MoveContents(WebContents* source,
333 const gfx::Rect& pos) {
334 // Do nothing.
335 }
336
337 // TODO(merge): WARNING! method no longer available on the base class.
338 // See http://b/issue?id=5862108
339 void ContentViewClient::URLStarredChanged(WebContents* source, bool starred) {
340 JNIEnv* env = AttachCurrentThread();
341 Java_ContentViewClient_onUrlStarredChanged(env,
342 weak_java_client_.get(env).obj(),
343 starred);
344 }
345
346 // This is either called from TabContents::DidNavigateMainFramePostCommit() with
347 // an empty GURL or responding to RenderViewHost::OnMsgUpateTargetURL(). In
348 // Chrome, the latter is not always called, especially not during history
349 // navigation. So we only handle the first case and pass the source TabContents'
350 // url to Java to update the UI.
351 void ContentViewClient::UpdateTargetURL(WebContents* source,
352 int32 page_id,
353 const GURL& url) {
354 if (url.is_empty()) {
355 JNIEnv* env = AttachCurrentThread();
356 ScopedJavaLocalRef<jstring> java_url =
357 ConvertUTF8ToJavaString(env, source->GetURL().spec());
358 Java_ContentViewClient_onUpdateUrl(env,
359 weak_java_client_.get(env).obj(),
360 java_url.obj());
361 }
362 }
363
364 bool ContentViewClient::CanDownload(RenderViewHost* source,
365 int request_id,
366 const std::string& request_method) {
367 if (request_method == net::HttpRequestHeaders::kGetMethod) {
368 content::DownloadController::GetInstance()->CreateGETDownload(
369 source, request_id);
370 return false;
371 }
372 return true;
373 }
374
375 void ContentViewClient::OnStartDownload(WebContents* source,
376 DownloadItem* download) {
377 content::DownloadController::GetInstance()->OnPostDownloadStarted(
378 source, download);
379 }
380
381 void ContentViewClient::FindReply(WebContents* web_contents,
382 int request_id,
383 int number_of_matches,
384 const gfx::Rect& selection_rect,
385 int active_match_ordinal,
386 bool final_update) {
387 /* TODO(jrg): upstream this; requires
388 content/browser/android/find_helper.h to be upstreamed */
389 }
390
391 void ContentViewClient::OnReceiveFindMatchRects(
392 int version, const std::vector<FindMatchRect>& rects,
393 const FindMatchRect& active_rect) {
394 JNIEnv* env = AttachCurrentThread();
395
396 // Constructs an float[] of (left, top, right, bottom) tuples and passes it on
397 // to the Java onReceiveFindMatchRects handler which will use it to create
398 // RectF objects equivalent to the std::vector<FindMatchRect>.
399 ScopedJavaLocalRef<jfloatArray> rect_data(env,
400 env->NewFloatArray(rects.size() * 4));
401 jfloat* rect_data_floats = env->GetFloatArrayElements(rect_data.obj(), NULL);
402 for (size_t i = 0; i < rects.size(); ++i) {
403 rect_data_floats[4 * i] = rects[i].left;
404 rect_data_floats[4 * i + 1] = rects[i].top;
405 rect_data_floats[4 * i + 2] = rects[i].right;
406 rect_data_floats[4 * i + 3] = rects[i].bottom;
407 }
408 env->ReleaseFloatArrayElements(rect_data.obj(), rect_data_floats, 0);
409
410 ScopedJavaLocalRef<jobject> active_rect_object;
411 if (active_rect.left < active_rect.right &&
412 active_rect.top < active_rect.bottom) {
413 ScopedJavaLocalRef<jclass> rect_clazz =
414 GetClass(env, "android/graphics/RectF");
415 jmethodID rect_constructor =
416 GetMethodID(env, rect_clazz, "<init>", "(FFFF)V");
417 active_rect_object.Reset(env, env->NewObject(rect_clazz.obj(),
418 rect_constructor,
419 active_rect.left,
420 active_rect.top,
421 active_rect.right,
422 active_rect.bottom));
423 DCHECK(!active_rect_object.is_null());
424 }
425
426
427 Java_ContentViewClient_onReceiveFindMatchRects(
428 env,
429 weak_java_client_.get(env).obj(),
430 version, rect_data.obj(),
431 active_rect_object.obj());
432 }
433
434 bool ContentViewClient::ShouldOverrideLoading(const GURL& url) {
435 if (!url.is_valid())
436 return false;
437
438 JNIEnv* env = AttachCurrentThread();
439 ScopedJavaLocalRef<jstring> jstring_url =
440 ConvertUTF8ToJavaString(env, url.spec());
441 bool ret = Java_ContentViewClient_shouldOverrideUrlLoading(
442 env, weak_java_client_.get(env).obj(), jstring_url.obj());
443 return ret;
444 }
445
446 void ContentViewClient::HandleKeyboardEvent(
447 const NativeWebKeyboardEvent& event) {
448 /* TODO(jrg): to upstream this implementation, we need these files as well:
449 browser/android/ime_helper.cc
450 browser/android/ime_helper.h
451 browser/renderer_host/native_web_keyboard_event_android.h
452 browser/renderer_host/native_web_keyboard_event_android.cc
453 Also the @CalledByNative handleKeyboardEvent() in ContentViewClient.java.
454 */
455 NOTREACHED();
456 }
457
458 bool ContentViewClient::TakeFocus(bool reverse) {
459 JNIEnv* env = AttachCurrentThread();
460 return Java_ContentViewClient_takeFocus(env,
461 weak_java_client_.get(env).obj(),
462 reverse);
463 }
464
465 ContentViewClientError ContentViewClient::ToContentViewClientError(int net_error )
466 {
467 // Note: many net::Error constants don't have an obvious mapping.
468 // These will be handled by the default case, ERROR_UNKNOWN.
469 switch(net_error) {
470 case ERR_UNSUPPORTED_AUTH_SCHEME:
471 return CONTENT_VIEW_CLIENT_ERROR_UNSUPPORTED_AUTH_SCHEME;
472
473 case ERR_INVALID_AUTH_CREDENTIALS:
474 case ERR_MISSING_AUTH_CREDENTIALS:
475 case ERR_MISCONFIGURED_AUTH_ENVIRONMENT:
476 return CONTENT_VIEW_CLIENT_ERROR_AUTHENTICATION;
477
478 case ERR_TOO_MANY_REDIRECTS:
479 return CONTENT_VIEW_CLIENT_ERROR_REDIRECT_LOOP;
480
481 case ERR_UPLOAD_FILE_CHANGED:
482 return CONTENT_VIEW_CLIENT_ERROR_FILE_NOT_FOUND;
483
484 case ERR_INVALID_URL:
485 return CONTENT_VIEW_CLIENT_ERROR_BAD_URL;
486
487 case ERR_DISALLOWED_URL_SCHEME:
488 case ERR_UNKNOWN_URL_SCHEME:
489 return CONTENT_VIEW_CLIENT_ERROR_UNSUPPORTED_SCHEME;
490
491 case ERR_IO_PENDING:
492 case ERR_NETWORK_IO_SUSPENDED:
493 return CONTENT_VIEW_CLIENT_ERROR_IO;
494
495 case ERR_CONNECTION_TIMED_OUT:
496 case ERR_TIMED_OUT:
497 return CONTENT_VIEW_CLIENT_ERROR_TIMEOUT;
498
499 case ERR_FILE_TOO_BIG:
500 return CONTENT_VIEW_CLIENT_ERROR_FILE;
501
502 case ERR_HOST_RESOLVER_QUEUE_TOO_LARGE:
503 case ERR_INSUFFICIENT_RESOURCES:
504 case ERR_OUT_OF_MEMORY:
505 return CONTENT_VIEW_CLIENT_ERROR_TOO_MANY_REQUESTS;
506
507 case ERR_CONNECTION_CLOSED:
508 case ERR_CONNECTION_RESET:
509 case ERR_CONNECTION_REFUSED:
510 case ERR_CONNECTION_ABORTED:
511 case ERR_CONNECTION_FAILED:
512 case ERR_SOCKET_NOT_CONNECTED:
513 return CONTENT_VIEW_CLIENT_ERROR_CONNECT;
514
515 case ERR_INTERNET_DISCONNECTED:
516 case ERR_ADDRESS_INVALID:
517 case ERR_ADDRESS_UNREACHABLE:
518 case ERR_NAME_NOT_RESOLVED:
519 case ERR_NAME_RESOLUTION_FAILED:
520 return CONTENT_VIEW_CLIENT_ERROR_HOST_LOOKUP;
521
522 case ERR_SSL_PROTOCOL_ERROR:
523 case ERR_SSL_CLIENT_AUTH_CERT_NEEDED:
524 case ERR_TUNNEL_CONNECTION_FAILED:
525 case ERR_NO_SSL_VERSIONS_ENABLED:
526 case ERR_SSL_VERSION_OR_CIPHER_MISMATCH:
527 case ERR_SSL_RENEGOTIATION_REQUESTED:
528 case ERR_CERT_ERROR_IN_SSL_RENEGOTIATION:
529 case ERR_BAD_SSL_CLIENT_AUTH_CERT:
530 case ERR_SSL_NO_RENEGOTIATION:
531 case ERR_SSL_DECOMPRESSION_FAILURE_ALERT:
532 case ERR_SSL_BAD_RECORD_MAC_ALERT:
533 case ERR_SSL_UNSAFE_NEGOTIATION:
534 case ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY:
535 case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED:
536 case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY:
537 return CONTENT_VIEW_CLIENT_ERROR_FAILED_SSL_HANDSHAKE;
538
539 case ERR_PROXY_AUTH_UNSUPPORTED:
540 case ERR_PROXY_AUTH_REQUESTED:
541 case ERR_PROXY_CONNECTION_FAILED:
542 case ERR_UNEXPECTED_PROXY_AUTH:
543 return CONTENT_VIEW_CLIENT_ERROR_PROXY_AUTHENTICATION;
544
545 /* The certificate errors are handled by onReceivedSslError
546 * and don't need to be reported here.
547 */
548 case ERR_CERT_COMMON_NAME_INVALID:
549 case ERR_CERT_DATE_INVALID:
550 case ERR_CERT_AUTHORITY_INVALID:
551 case ERR_CERT_CONTAINS_ERRORS:
552 case ERR_CERT_NO_REVOCATION_MECHANISM:
553 case ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
554 case ERR_CERT_REVOKED:
555 case ERR_CERT_INVALID:
556 case ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
557 case ERR_CERT_NOT_IN_DNS:
558 case ERR_CERT_NON_UNIQUE_NAME:
559 return CONTENT_VIEW_CLIENT_ERROR_OK;
560
561 default:
562 VLOG(1) << "ContentViewClient::ToContentViewClientError: Unknown "
563 << "chromium error: "
564 << net_error;
565 return CONTENT_VIEW_CLIENT_ERROR_UNKNOWN;
566 }
567 }
568
569 content::JavaScriptDialogCreator*
570 ContentViewClient::GetJavaScriptDialogCreator() {
571 return javascript_dialog_creator_;
572 }
573
574 void ContentViewClient::RunFileChooser(
575 WebContents* tab, const content::FileChooserParams& params) {
576 JNIEnv* env = AttachCurrentThread();
577 ScopedJavaLocalRef<jobject> jparams = ToJavaFileChooserParams(env, params);
578 Java_ContentViewClient_runFileChooser(env, weak_java_client_.get(env).obj(),
579 jparams.obj());
580 }
581
582 // ----------------------------------------------------------------------------
583 // Native JNI methods
584 // ----------------------------------------------------------------------------
585
586 // Register native methods
587
588 bool RegisterContentViewClient(JNIEnv* env) {
589 if (!HasClass(env, kContentViewClientClassPath)) {
590 DLOG(ERROR) << "Unable to find class ContentViewClient!";
591 return false;
592 }
593 return RegisterNativesImpl(env);
594 }
595
596 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698