 Chromium Code Reviews
 Chromium Code Reviews Issue 10536066:
  android content shell bringup.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 10536066:
  android content shell bringup.  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| Index: content/browser/android/content_view_client.cc | 
| diff --git a/content/browser/android/content_view_client.cc b/content/browser/android/content_view_client.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..e7147cc403f794c3265045779ae8df478dcc43d4 | 
| --- /dev/null | 
| +++ b/content/browser/android/content_view_client.cc | 
| @@ -0,0 +1,592 @@ | 
| +// Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "content/browser/android/content_view_client.h" | 
| + | 
| +#include <android/keycodes.h> | 
| + | 
| +#include "base/android/jni_android.h" | 
| +#include "base/android/jni_string.h" | 
| +#include "content/browser/android/content_util.h" | 
| +#include "content/public/browser/content_view.h" | 
| 
jam
2012/06/08 23:45:09
nit: order
 
jam
2012/06/12 17:44:02
?
 
John Grabowski
2012/06/13 22:12:29
Done.
 | 
| +#include "content/browser/android/download_controller.h" | 
| +#include "content/browser/renderer_host/render_view_host_impl.h" | 
| +#include "content/public/browser/render_widget_host_view.h" | 
| +#include "content/public/browser/download_item.h" | 
| +#include "content/public/browser/invalidate_type.h" | 
| +#include "content/public/browser/page_navigator.h" | 
| +#include "content/public/browser/navigation_controller.h" | 
| +#include "content/public/browser/navigation_entry.h" | 
| +#include "content/public/browser/web_contents.h" | 
| +#include "content/public/common/find_match_rect_android.h" | 
| +#include "content/public/common/page_transition_types.h" | 
| +#include "content/public/common/referrer.h" | 
| +#include "jni/content_view_client_jni.h" | 
| +#include "net/http/http_request_headers.h" | 
| +#include "ui/gfx/rect.h" | 
| +#include "webkit/glue/window_open_disposition.h" | 
| + | 
| +using base::android::AttachCurrentThread; | 
| +using base::android::CheckException; | 
| +using base::android::ConvertUTF8ToJavaString; | 
| +using base::android::ConvertUTF16ToJavaString; | 
| +using base::android::GetClass; | 
| +using base::android::GetMethodID; | 
| +using base::android::HasClass; | 
| +using base::android::ScopedJavaLocalRef; | 
| +using content::DownloadItem; | 
| +using content::RenderViewHost; | 
| +using content::WebContents; | 
| + | 
| +using namespace net; | 
| + | 
| +ContentViewClient::ContentViewClient(JNIEnv* env, jobject obj) | 
| + : weak_java_client_(env, obj), | 
| + find_helper_(NULL), | 
| + javascript_dialog_creator_(NULL) { | 
| +} | 
| + | 
| +ContentViewClient::~ContentViewClient() { | 
| +} | 
| + | 
| +// static | 
| +ContentViewClient* ContentViewClient::CreateNativeContentViewClient( | 
| + JNIEnv* env, jobject obj) { | 
| + if (!obj) | 
| 
jam
2012/06/08 23:45:09
is this an error that shouldn't happen? if so, jus
 
jam
2012/06/12 17:44:02
?
 
John Grabowski
2012/06/13 22:12:29
Done.
 | 
| + return NULL; | 
| + | 
| + return new ContentViewClient(env, obj); | 
| +} | 
| + | 
| +void ContentViewClient::OnInternalPageLoadRequest( | 
| + content::WebContents* source, const GURL& url) { | 
| + last_requested_navigation_url_ = url; | 
| +} | 
| + | 
| + | 
| +void ContentViewClient::OnPageStarted(const GURL& url) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + ScopedJavaLocalRef<jstring> jstring_url = | 
| + ConvertUTF8ToJavaString(env, url.spec()); | 
| + Java_ContentViewClient_onPageStarted(env, weak_java_client_.get(env).obj(), | 
| + jstring_url.obj()); | 
| +} | 
| + | 
| +void ContentViewClient::OnPageFinished(const GURL& url) { | 
| + if (url == last_requested_navigation_url_) | 
| + last_requested_navigation_url_ = GURL::EmptyGURL(); | 
| + | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + ScopedJavaLocalRef<jstring> jstring_url = | 
| + ConvertUTF8ToJavaString(env, url.spec()); | 
| + | 
| + Java_ContentViewClient_onPageFinished(env, weak_java_client_.get(env).obj(), | 
| + jstring_url.obj()); | 
| + CheckException(env); | 
| +} | 
| + | 
| +void ContentViewClient::OnReceivedError(int error_code, | 
| + const string16& description, | 
| + const GURL& url) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + ScopedJavaLocalRef<jstring> jstring_error_description = | 
| + ConvertUTF8ToJavaString(env, url.spec()); | 
| + ScopedJavaLocalRef<jstring> jstring_url = | 
| + ConvertUTF8ToJavaString(env, url.spec()); | 
| + | 
| + Java_ContentViewClient_onReceivedError( | 
| + env, weak_java_client_.get(env).obj(), | 
| + ToContentViewClientError(error_code), | 
| + jstring_error_description.obj(), jstring_url.obj()); | 
| +} | 
| + | 
| +void ContentViewClient::OnReceivedHttpAuthRequest( | 
| + jobject auth_handler, | 
| + const string16& host, | 
| + const string16& realm) { | 
| + /* TODO(jrg): upstream this once ContentHttpAuthHandler.java is | 
| + upstreamed, and onReceivedHttpAuthRequest() is upstreamed in | 
| + ContentViewClient.java */ | 
| + NOTREACHED(); | 
| +} | 
| + | 
| +void ContentViewClient::OnDidCommitMainFrame(const GURL& url, | 
| + const GURL& base_url) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + ScopedJavaLocalRef<jstring> jstring_url = | 
| + ConvertUTF8ToJavaString(env, url.spec()); | 
| + ScopedJavaLocalRef<jstring> jstring_base_url = | 
| + ConvertUTF8ToJavaString(env, base_url.spec()); | 
| + | 
| + Java_ContentViewClient_onMainFrameCommitted( | 
| + env, weak_java_client_.get(env).obj(), | 
| + jstring_url.obj(), jstring_base_url.obj()); | 
| +} | 
| + | 
| +void ContentViewClient::OnInterstitialShown() { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + Java_ContentViewClient_onInterstitialShown( | 
| + env, weak_java_client_.get(env).obj()); | 
| +} | 
| + | 
| +void ContentViewClient::OnInterstitialHidden() { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + Java_ContentViewClient_onInterstitialHidden( | 
| + env, weak_java_client_.get(env).obj()); | 
| +} | 
| + | 
| +void ContentViewClient::SetFindHelper(FindHelper* find_helper) { | 
| + find_helper_ = find_helper; | 
| +} | 
| + | 
| +void ContentViewClient::SetJavaScriptDialogCreator( | 
| + content::JavaScriptDialogCreator* javascript_dialog_creator) { | 
| + javascript_dialog_creator_ = javascript_dialog_creator; | 
| +} | 
| + | 
| +bool ContentViewClient::OnJSModalDialog(content::JavaScriptMessageType type, | 
| + bool is_before_unload_dialog, | 
| + const GURL& url, | 
| + const string16& message, | 
| + const string16& default_value) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + ScopedJavaLocalRef<jstring> jurl(ConvertUTF8ToJavaString(env, url.spec())); | 
| + ScopedJavaLocalRef<jstring> jmessage(ConvertUTF16ToJavaString(env, message)); | 
| + | 
| + // Special case for beforeunload dialogs, as that isn't encoded in the | 
| + // |type| of the dialog. | 
| + if (is_before_unload_dialog) { | 
| + return Java_ContentViewClient_onJsBeforeUnload(env, | 
| + weak_java_client_.get(env).obj(), | 
| + jurl.obj(), | 
| + jmessage.obj()); | 
| + } | 
| + | 
| + switch (type) { | 
| + case content::JAVASCRIPT_MESSAGE_TYPE_ALERT: | 
| + return Java_ContentViewClient_onJsAlert(env, | 
| + weak_java_client_.get(env).obj(), | 
| + jurl.obj(), | 
| + jmessage.obj()); | 
| + | 
| + case content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM: | 
| + return Java_ContentViewClient_onJsConfirm(env, | 
| + weak_java_client_.get(env).obj(), | 
| + jurl.obj(), | 
| + jmessage.obj()); | 
| + | 
| + case content::JAVASCRIPT_MESSAGE_TYPE_PROMPT: { | 
| + ScopedJavaLocalRef<jstring> jdefault_value( | 
| + ConvertUTF16ToJavaString(env, default_value)); | 
| + return Java_ContentViewClient_onJsPrompt(env, | 
| + weak_java_client_.get(env).obj(), | 
| + jurl.obj(), | 
| + jmessage.obj(), | 
| + jdefault_value.obj()); | 
| + } | 
| + | 
| + default: | 
| + NOTREACHED(); | 
| + return false; | 
| + } | 
| +} | 
| + | 
| +// ---------------------------------------------------------------------------- | 
| +// WebContentsDelegate methods | 
| +// ---------------------------------------------------------------------------- | 
| + | 
| +// OpenURLFromTab() will be called when we're performing a browser-intiated | 
| +// navigation. The most common scenario for this is opening new tabs (see | 
| +// RenderViewImpl::decidePolicyForNavigation for more details). | 
| +WebContents* ContentViewClient::OpenURLFromTab( | 
| + WebContents* source, | 
| + const content::OpenURLParams& params) { | 
| + const GURL& url = params.url; | 
| + WindowOpenDisposition disposition = params.disposition; | 
| + content::PageTransition transition( | 
| + content::PageTransitionFromInt(params.transition)); | 
| + | 
| + if (!source || (disposition != CURRENT_TAB && | 
| + disposition != NEW_FOREGROUND_TAB && | 
| + disposition != NEW_BACKGROUND_TAB && | 
| + disposition != OFF_THE_RECORD)) { | 
| + NOTIMPLEMENTED(); | 
| + return NULL; | 
| + } | 
| + | 
| + if (disposition == NEW_FOREGROUND_TAB || | 
| + disposition == NEW_BACKGROUND_TAB || | 
| + disposition == OFF_THE_RECORD) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + ScopedJavaLocalRef<jstring> java_url = | 
| + ConvertUTF8ToJavaString(env, url.spec()); | 
| + Java_ContentViewClient_openNewTab(env, | 
| + weak_java_client_.get(env).obj(), | 
| + java_url.obj(), | 
| + disposition == OFF_THE_RECORD); | 
| + return NULL; | 
| + } | 
| + | 
| + // TODO(mkosiba): This should be in platform_utils OpenExternal, b/6174564. | 
| + if (transition == content::PAGE_TRANSITION_LINK && | 
| + ShouldOverrideLoading(url)) | 
| + return NULL; | 
| + | 
| + source->GetController().LoadURL(url, params.referrer, transition, | 
| + std::string()); | 
| + return source; | 
| +} | 
| + | 
| +// ShouldIgnoreNavigation will be called for every non-local top level | 
| +// navigation made by the renderer. If true is returned the renderer will | 
| +// not perform the navigation. This is done by using synchronous IPC so we | 
| +// should avoid blocking calls from this method. | 
| +bool ContentViewClient::ShouldIgnoreNavigation( | 
| + WebContents* source, | 
| + const GURL& url, | 
| + const content::Referrer& referrer, | 
| + WindowOpenDisposition disposition, | 
| + content::PageTransition transition_type) { | 
| + | 
| + // Don't override new tabs. | 
| + if (disposition == NEW_FOREGROUND_TAB || | 
| + disposition == NEW_BACKGROUND_TAB || | 
| + disposition == OFF_THE_RECORD) | 
| + return false; | 
| + | 
| + // Don't override the navigation that has just been requested via the | 
| + // ContentView.loadUrl method. | 
| + if (url == last_requested_navigation_url_) { | 
| + last_requested_navigation_url_ = GURL::EmptyGURL(); | 
| + return false; | 
| + } | 
| + | 
| + return ShouldOverrideLoading(url); | 
| +} | 
| + | 
| +void ContentViewClient::NavigationStateChanged( | 
| + const WebContents* source, unsigned changed_flags) { | 
| + if (changed_flags & ( | 
| + content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + Java_ContentViewClient_onTabHeaderStateChanged( | 
| + env, weak_java_client_.get(env).obj()); | 
| + } | 
| +} | 
| + | 
| +void ContentViewClient::AddNewContents(WebContents* source, | 
| + WebContents* new_contents, | 
| + WindowOpenDisposition disposition, | 
| + const gfx::Rect& initial_pos, | 
| + bool user_gesture) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + bool handled = Java_ContentViewClient_addNewContents( | 
| + env, | 
| + weak_java_client_.get(env).obj(), | 
| + reinterpret_cast<jint>(source), | 
| + reinterpret_cast<jint>(new_contents), | 
| + static_cast<jint>(disposition), | 
| + NULL, | 
| + user_gesture); | 
| + if (!handled) | 
| + delete new_contents; | 
| +} | 
| + | 
| +void ContentViewClient::ActivateContents(WebContents* contents) { | 
| + // TODO(dtrainor) When doing the merge I came across this. Should we be | 
| + // activating this tab here? | 
| +} | 
| + | 
| +void ContentViewClient::DeactivateContents(WebContents* contents) { | 
| + // Do nothing. | 
| +} | 
| + | 
| +void ContentViewClient::LoadingStateChanged(WebContents* source) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + bool has_stopped = source == NULL || !source->IsLoading(); | 
| + | 
| + if (has_stopped) | 
| + Java_ContentViewClient_onLoadStopped( | 
| + env, weak_java_client_.get(env).obj()); | 
| + else | 
| + Java_ContentViewClient_onLoadStarted( | 
| + env, weak_java_client_.get(env).obj()); | 
| +} | 
| + | 
| +void ContentViewClient::LoadProgressChanged(double progress) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + Java_ContentViewClient_onLoadProgressChanged( | 
| + env, | 
| + weak_java_client_.get(env).obj(), | 
| + progress); | 
| +} | 
| + | 
| +void ContentViewClient::CloseContents(WebContents* source) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + Java_ContentViewClient_closeContents(env, weak_java_client_.get(env).obj()); | 
| +} | 
| + | 
| +void ContentViewClient::MoveContents(WebContents* source, | 
| + const gfx::Rect& pos) { | 
| + // Do nothing. | 
| +} | 
| + | 
| +// TODO(merge): WARNING! method no longer available on the base class. | 
| +// See http://b/issue?id=5862108 | 
| +void ContentViewClient::URLStarredChanged(WebContents* source, bool starred) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + Java_ContentViewClient_onUrlStarredChanged(env, | 
| + weak_java_client_.get(env).obj(), | 
| + starred); | 
| +} | 
| + | 
| +// This is either called from TabContents::DidNavigateMainFramePostCommit() with | 
| +// an empty GURL or responding to RenderViewHost::OnMsgUpateTargetURL(). In | 
| +// Chrome, the latter is not always called, especially not during history | 
| +// navigation. So we only handle the first case and pass the source TabContents' | 
| +// url to Java to update the UI. | 
| +void ContentViewClient::UpdateTargetURL(WebContents* source, | 
| + int32 page_id, | 
| + const GURL& url) { | 
| + if (url.is_empty()) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + ScopedJavaLocalRef<jstring> java_url = | 
| + ConvertUTF8ToJavaString(env, source->GetURL().spec()); | 
| + Java_ContentViewClient_onUpdateUrl(env, | 
| + weak_java_client_.get(env).obj(), | 
| + java_url.obj()); | 
| + } | 
| +} | 
| + | 
| +bool ContentViewClient::CanDownload(RenderViewHost* source, | 
| + int request_id, | 
| + const std::string& request_method) { | 
| + if (request_method == net::HttpRequestHeaders::kGetMethod) { | 
| + content::DownloadController::GetInstance()->CreateGETDownload( | 
| + source, request_id); | 
| + return false; | 
| + } | 
| + return true; | 
| +} | 
| + | 
| +void ContentViewClient::OnStartDownload(WebContents* source, | 
| + DownloadItem* download) { | 
| + content::DownloadController::GetInstance()->OnPostDownloadStarted( | 
| + source, download); | 
| +} | 
| + | 
| +void ContentViewClient::FindReply(WebContents* web_contents, | 
| + int request_id, | 
| + int number_of_matches, | 
| + const gfx::Rect& selection_rect, | 
| + int active_match_ordinal, | 
| + bool final_update) { | 
| + /* TODO(jrg): upstream this; requires | 
| + content/browser/android/find_helper.h to be upstreamed */ | 
| +} | 
| + | 
| +void ContentViewClient::OnReceiveFindMatchRects( | 
| + int version, const std::vector<FindMatchRect>& rects, | 
| + const FindMatchRect& active_rect) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + | 
| + // Constructs an float[] of (left, top, right, bottom) tuples and passes it on | 
| + // to the Java onReceiveFindMatchRects handler which will use it to create | 
| + // RectF objects equivalent to the std::vector<FindMatchRect>. | 
| + ScopedJavaLocalRef<jfloatArray> rect_data(env, | 
| + env->NewFloatArray(rects.size() * 4)); | 
| + jfloat* rect_data_floats = env->GetFloatArrayElements(rect_data.obj(), NULL); | 
| + for (size_t i = 0; i < rects.size(); ++i) { | 
| + rect_data_floats[4 * i] = rects[i].left; | 
| + rect_data_floats[4 * i + 1] = rects[i].top; | 
| + rect_data_floats[4 * i + 2] = rects[i].right; | 
| + rect_data_floats[4 * i + 3] = rects[i].bottom; | 
| + } | 
| + env->ReleaseFloatArrayElements(rect_data.obj(), rect_data_floats, 0); | 
| + | 
| + ScopedJavaLocalRef<jobject> active_rect_object; | 
| + if (active_rect.left < active_rect.right && | 
| + active_rect.top < active_rect.bottom) { | 
| + ScopedJavaLocalRef<jclass> rect_clazz = | 
| + GetClass(env, "android/graphics/RectF"); | 
| + jmethodID rect_constructor = | 
| + GetMethodID(env, rect_clazz, "<init>", "(FFFF)V"); | 
| + active_rect_object.Reset(env, env->NewObject(rect_clazz.obj(), | 
| + rect_constructor, | 
| + active_rect.left, | 
| + active_rect.top, | 
| + active_rect.right, | 
| + active_rect.bottom)); | 
| + DCHECK(!active_rect_object.is_null()); | 
| + } | 
| + | 
| + | 
| + Java_ContentViewClient_onReceiveFindMatchRects( | 
| + env, | 
| + weak_java_client_.get(env).obj(), | 
| + version, rect_data.obj(), | 
| + active_rect_object.obj()); | 
| +} | 
| + | 
| +bool ContentViewClient::ShouldOverrideLoading(const GURL& url) { | 
| + if (!url.is_valid()) | 
| + return false; | 
| + | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + ScopedJavaLocalRef<jstring> jstring_url = | 
| + ConvertUTF8ToJavaString(env, url.spec()); | 
| + bool ret = Java_ContentViewClient_shouldOverrideUrlLoading( | 
| + env, weak_java_client_.get(env).obj(), jstring_url.obj()); | 
| + return ret; | 
| +} | 
| + | 
| +void ContentViewClient::HandleKeyboardEvent( | 
| + const NativeWebKeyboardEvent& event) { | 
| + /* TODO(jrg): to upstream this implementation, we need these files as well: | 
| + browser/android/ime_helper.cc | 
| + browser/android/ime_helper.h | 
| + browser/renderer_host/native_web_keyboard_event_android.h | 
| + browser/renderer_host/native_web_keyboard_event_android.cc | 
| + Also the @CalledByNative handleKeyboardEvent() in ContentViewClient.java. | 
| + */ | 
| + NOTREACHED(); | 
| +} | 
| + | 
| +bool ContentViewClient::TakeFocus(bool reverse) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + return Java_ContentViewClient_takeFocus(env, | 
| + weak_java_client_.get(env).obj(), | 
| + reverse); | 
| +} | 
| + | 
| +ContentViewClientError ContentViewClient::ToContentViewClientError(int netError) | 
| +{ | 
| 
jam
2012/06/08 23:45:09
nit: brace in above line
 
jam
2012/06/12 17:44:02
this is still not according to style guide, i.e 80
 
John Grabowski
2012/06/13 22:12:29
Done.
 | 
| + // Note: many net::Error constants don't have an obvious mapping. | 
| + // These will be handled by the default case, ERROR_UNKNOWN. | 
| + switch(netError) { | 
| + case ERR_UNSUPPORTED_AUTH_SCHEME: | 
| 
jam
2012/06/08 23:45:09
nit: here and below, 2 space indents
 
jam
2012/06/12 17:44:02
?
 
John Grabowski
2012/06/13 22:12:29
Done.  (sorry looks like I missed this whole file
 | 
| + return ERROR_UNSUPPORTED_AUTH_SCHEME; | 
| + | 
| + case ERR_INVALID_AUTH_CREDENTIALS: | 
| + case ERR_MISSING_AUTH_CREDENTIALS: | 
| + case ERR_MISCONFIGURED_AUTH_ENVIRONMENT: | 
| + return ERROR_AUTHENTICATION; | 
| + | 
| + case ERR_TOO_MANY_REDIRECTS: | 
| + return ERROR_REDIRECT_LOOP; | 
| + | 
| + case ERR_UPLOAD_FILE_CHANGED: | 
| + return ERROR_FILE_NOT_FOUND; | 
| + | 
| + case ERR_INVALID_URL: | 
| + return ERROR_BAD_URL; | 
| + | 
| + case ERR_DISALLOWED_URL_SCHEME: | 
| + case ERR_UNKNOWN_URL_SCHEME: | 
| + return ERROR_UNSUPPORTED_SCHEME; | 
| + | 
| + case ERR_IO_PENDING: | 
| + case ERR_NETWORK_IO_SUSPENDED: | 
| + return ERROR_IO; | 
| + | 
| + case ERR_CONNECTION_TIMED_OUT: | 
| + case ERR_TIMED_OUT: | 
| + return ERROR_TIMEOUT; | 
| + | 
| + case ERR_FILE_TOO_BIG: | 
| + return ERROR_FILE; | 
| + | 
| + case ERR_HOST_RESOLVER_QUEUE_TOO_LARGE: | 
| + case ERR_INSUFFICIENT_RESOURCES: | 
| + case ERR_OUT_OF_MEMORY: | 
| + return ERROR_TOO_MANY_REQUESTS; | 
| + | 
| + case ERR_CONNECTION_CLOSED: | 
| + case ERR_CONNECTION_RESET: | 
| + case ERR_CONNECTION_REFUSED: | 
| + case ERR_CONNECTION_ABORTED: | 
| + case ERR_CONNECTION_FAILED: | 
| + case ERR_SOCKET_NOT_CONNECTED: | 
| + return ERROR_CONNECT; | 
| + | 
| + case ERR_INTERNET_DISCONNECTED: | 
| + case ERR_ADDRESS_INVALID: | 
| + case ERR_ADDRESS_UNREACHABLE: | 
| + case ERR_NAME_NOT_RESOLVED: | 
| + case ERR_NAME_RESOLUTION_FAILED: | 
| + return ERROR_HOST_LOOKUP; | 
| + | 
| + case ERR_SSL_PROTOCOL_ERROR: | 
| + case ERR_SSL_CLIENT_AUTH_CERT_NEEDED: | 
| + case ERR_TUNNEL_CONNECTION_FAILED: | 
| + case ERR_NO_SSL_VERSIONS_ENABLED: | 
| + case ERR_SSL_VERSION_OR_CIPHER_MISMATCH: | 
| + case ERR_SSL_RENEGOTIATION_REQUESTED: | 
| + case ERR_CERT_ERROR_IN_SSL_RENEGOTIATION: | 
| + case ERR_BAD_SSL_CLIENT_AUTH_CERT: | 
| + case ERR_SSL_NO_RENEGOTIATION: | 
| + case ERR_SSL_DECOMPRESSION_FAILURE_ALERT: | 
| + case ERR_SSL_BAD_RECORD_MAC_ALERT: | 
| + case ERR_SSL_UNSAFE_NEGOTIATION: | 
| + case ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY: | 
| + case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: | 
| + case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: | 
| + return ERROR_FAILED_SSL_HANDSHAKE; | 
| + | 
| + case ERR_PROXY_AUTH_UNSUPPORTED: | 
| + case ERR_PROXY_AUTH_REQUESTED: | 
| + case ERR_PROXY_CONNECTION_FAILED: | 
| + case ERR_UNEXPECTED_PROXY_AUTH: | 
| + return ERROR_PROXY_AUTHENTICATION; | 
| + | 
| + /* The certificate errors are handled by onReceivedSslError | 
| + * and don't need to be reported here. | 
| + */ | 
| + case ERR_CERT_COMMON_NAME_INVALID: | 
| + case ERR_CERT_DATE_INVALID: | 
| + case ERR_CERT_AUTHORITY_INVALID: | 
| + case ERR_CERT_CONTAINS_ERRORS: | 
| + case ERR_CERT_NO_REVOCATION_MECHANISM: | 
| + case ERR_CERT_UNABLE_TO_CHECK_REVOCATION: | 
| + case ERR_CERT_REVOKED: | 
| + case ERR_CERT_INVALID: | 
| + case ERR_CERT_WEAK_SIGNATURE_ALGORITHM: | 
| + case ERR_CERT_NOT_IN_DNS: | 
| + case ERR_CERT_NON_UNIQUE_NAME: | 
| + return ERROR_OK; | 
| + | 
| + default: | 
| + VLOG(1) << "ContentViewClient::ToContentViewClientError: Unknown " | 
| + << "chromium error: " | 
| + << netError; | 
| + return ERROR_UNKNOWN; | 
| + } | 
| +} | 
| + | 
| +content::JavaScriptDialogCreator* | 
| + ContentViewClient::GetJavaScriptDialogCreator() { | 
| + return javascript_dialog_creator_; | 
| +} | 
| + | 
| +void ContentViewClient::RunFileChooser( | 
| + WebContents* tab, const content::FileChooserParams& params) { | 
| + JNIEnv* env = AttachCurrentThread(); | 
| + ScopedJavaLocalRef<jobject> jparams = ToJavaFileChooserParams(env, params); | 
| + Java_ContentViewClient_runFileChooser(env, weak_java_client_.get(env).obj(), | 
| + jparams.obj()); | 
| +} | 
| + | 
| +// ---------------------------------------------------------------------------- | 
| +// Native JNI methods | 
| +// ---------------------------------------------------------------------------- | 
| + | 
| +// Register native methods | 
| + | 
| +bool RegisterContentViewClient(JNIEnv* env) { | 
| + if (!HasClass(env, kContentViewClientClassPath)) { | 
| + DLOG(ERROR) << "Unable to find class ContentViewClient!"; | 
| + return false; | 
| + } | 
| + return RegisterNativesImpl(env); | 
| +} |