| 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..983db4f77b8e5d1ffcd1a39949d82422bd303725 | 
| --- /dev/null | 
| +++ b/content/browser/android/content_view_client.cc | 
| @@ -0,0 +1,587 @@ | 
| +// 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/browser/android/content_view_impl.h" | 
| +#include "content/browser/android/download_controller.h" | 
| +#include "content/browser/renderer_host/render_view_host_impl.h" | 
| +#include "content/common/find_match_rect_android.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/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; | 
| + | 
| +namespace content { | 
| + | 
| +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) { | 
| +  DCHECK(obj); | 
| +  return new ContentViewClient(env, obj); | 
| +} | 
| + | 
| +void ContentViewClient::OnInternalPageLoadRequest( | 
| +    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( | 
| +    JavaScriptDialogCreator* javascript_dialog_creator) { | 
| +  javascript_dialog_creator_ = javascript_dialog_creator; | 
| +} | 
| + | 
| +bool ContentViewClient::OnJSModalDialog(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 JAVASCRIPT_MESSAGE_TYPE_ALERT: | 
| +      return Java_ContentViewClient_onJsAlert(env, | 
| +                                              weak_java_client_.get(env).obj(), | 
| +                                              jurl.obj(), | 
| +                                              jmessage.obj()); | 
| + | 
| +    case JAVASCRIPT_MESSAGE_TYPE_CONFIRM: | 
| +      return Java_ContentViewClient_onJsConfirm(env, | 
| +          weak_java_client_.get(env).obj(), | 
| +          jurl.obj(), | 
| +          jmessage.obj()); | 
| + | 
| +    case 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 OpenURLParams& params) { | 
| +  const GURL& url = params.url; | 
| +  WindowOpenDisposition disposition = params.disposition; | 
| +  PageTransition transition( | 
| +      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 == 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 Referrer& referrer, | 
| +    WindowOpenDisposition disposition, | 
| +    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 & ( | 
| +      INVALIDATE_TYPE_TAB | 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) { | 
| +    DownloadController::GetInstance()->CreateGETDownload( | 
| +        source, request_id); | 
| +    return false; | 
| +  } | 
| +  return true; | 
| +} | 
| + | 
| +void ContentViewClient::OnStartDownload(WebContents* source, | 
| +                                        DownloadItem* download) { | 
| +  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 net_error) { | 
| +    // Note: many net::Error constants don't have an obvious mapping. | 
| +    // These will be handled by the default case, ERROR_UNKNOWN. | 
| +    switch(net_error) { | 
| +    case net::ERR_UNSUPPORTED_AUTH_SCHEME: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_UNSUPPORTED_AUTH_SCHEME; | 
| + | 
| +    case net::ERR_INVALID_AUTH_CREDENTIALS: | 
| +    case net::ERR_MISSING_AUTH_CREDENTIALS: | 
| +    case net::ERR_MISCONFIGURED_AUTH_ENVIRONMENT: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_AUTHENTICATION; | 
| + | 
| +    case net::ERR_TOO_MANY_REDIRECTS: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_REDIRECT_LOOP; | 
| + | 
| +    case net::ERR_UPLOAD_FILE_CHANGED: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_FILE_NOT_FOUND; | 
| + | 
| +    case net::ERR_INVALID_URL: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_BAD_URL; | 
| + | 
| +    case net::ERR_DISALLOWED_URL_SCHEME: | 
| +    case net::ERR_UNKNOWN_URL_SCHEME: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_UNSUPPORTED_SCHEME; | 
| + | 
| +    case net::ERR_IO_PENDING: | 
| +    case net::ERR_NETWORK_IO_SUSPENDED: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_IO; | 
| + | 
| +    case net::ERR_CONNECTION_TIMED_OUT: | 
| +    case net::ERR_TIMED_OUT: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_TIMEOUT; | 
| + | 
| +    case net::ERR_FILE_TOO_BIG: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_FILE; | 
| + | 
| +    case net::ERR_HOST_RESOLVER_QUEUE_TOO_LARGE: | 
| +    case net::ERR_INSUFFICIENT_RESOURCES: | 
| +    case net::ERR_OUT_OF_MEMORY: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_TOO_MANY_REQUESTS; | 
| + | 
| +    case net::ERR_CONNECTION_CLOSED: | 
| +    case net::ERR_CONNECTION_RESET: | 
| +    case net::ERR_CONNECTION_REFUSED: | 
| +    case net::ERR_CONNECTION_ABORTED: | 
| +    case net::ERR_CONNECTION_FAILED: | 
| +    case net::ERR_SOCKET_NOT_CONNECTED: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_CONNECT; | 
| + | 
| +    case net::ERR_INTERNET_DISCONNECTED: | 
| +    case net::ERR_ADDRESS_INVALID: | 
| +    case net::ERR_ADDRESS_UNREACHABLE: | 
| +    case net::ERR_NAME_NOT_RESOLVED: | 
| +    case net::ERR_NAME_RESOLUTION_FAILED: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_HOST_LOOKUP; | 
| + | 
| +    case net::ERR_SSL_PROTOCOL_ERROR: | 
| +    case net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED: | 
| +    case net::ERR_TUNNEL_CONNECTION_FAILED: | 
| +    case net::ERR_NO_SSL_VERSIONS_ENABLED: | 
| +    case net::ERR_SSL_VERSION_OR_CIPHER_MISMATCH: | 
| +    case net::ERR_SSL_RENEGOTIATION_REQUESTED: | 
| +    case net::ERR_CERT_ERROR_IN_SSL_RENEGOTIATION: | 
| +    case net::ERR_BAD_SSL_CLIENT_AUTH_CERT: | 
| +    case net::ERR_SSL_NO_RENEGOTIATION: | 
| +    case net::ERR_SSL_DECOMPRESSION_FAILURE_ALERT: | 
| +    case net::ERR_SSL_BAD_RECORD_MAC_ALERT: | 
| +    case net::ERR_SSL_UNSAFE_NEGOTIATION: | 
| +    case net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY: | 
| +    case net::ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: | 
| +    case net::ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_FAILED_SSL_HANDSHAKE; | 
| + | 
| +    case net::ERR_PROXY_AUTH_UNSUPPORTED: | 
| +    case net::ERR_PROXY_AUTH_REQUESTED: | 
| +    case net::ERR_PROXY_CONNECTION_FAILED: | 
| +    case net::ERR_UNEXPECTED_PROXY_AUTH: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_PROXY_AUTHENTICATION; | 
| + | 
| +      /* The certificate errors are handled by onReceivedSslError | 
| +       * and don't need to be reported here. | 
| +       */ | 
| +    case net::ERR_CERT_COMMON_NAME_INVALID: | 
| +    case net::ERR_CERT_DATE_INVALID: | 
| +    case net::ERR_CERT_AUTHORITY_INVALID: | 
| +    case net::ERR_CERT_CONTAINS_ERRORS: | 
| +    case net::ERR_CERT_NO_REVOCATION_MECHANISM: | 
| +    case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION: | 
| +    case net::ERR_CERT_REVOKED: | 
| +    case net::ERR_CERT_INVALID: | 
| +    case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM: | 
| +    case net::ERR_CERT_NOT_IN_DNS: | 
| +    case net::ERR_CERT_NON_UNIQUE_NAME: | 
| +      return CONTENT_VIEW_CLIENT_ERROR_OK; | 
| + | 
| +    default: | 
| +      VLOG(1) << "ContentViewClient::ToContentViewClientError: Unknown " | 
| +              << "chromium error: " | 
| +              << net_error; | 
| +      return CONTENT_VIEW_CLIENT_ERROR_UNKNOWN; | 
| +    } | 
| +} | 
| + | 
| +JavaScriptDialogCreator* ContentViewClient::GetJavaScriptDialogCreator() { | 
| +  return javascript_dialog_creator_; | 
| +} | 
| + | 
| +void ContentViewClient::RunFileChooser( | 
| +    WebContents* tab, const 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); | 
| +} | 
| + | 
| +}  // namespace content | 
|  |