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

Unified Diff: android_webview/native/aw_contents_client_bridge.cc

Issue 2863233002: [WebView] Move files from native to browser (Closed)
Patch Set: Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: android_webview/native/aw_contents_client_bridge.cc
diff --git a/android_webview/native/aw_contents_client_bridge.cc b/android_webview/native/aw_contents_client_bridge.cc
deleted file mode 100644
index b85568acfba18d76c31d7308ef09d492071de735..0000000000000000000000000000000000000000
--- a/android_webview/native/aw_contents_client_bridge.cc
+++ /dev/null
@@ -1,537 +0,0 @@
-// Copyright (c) 2013 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 "android_webview/native/aw_contents_client_bridge.h"
-
-#include <memory>
-#include <utility>
-
-#include "android_webview/common/devtools_instrumentation.h"
-#include "android_webview/grit/components_strings.h"
-#include "android_webview/native/aw_contents.h"
-#include "base/android/jni_android.h"
-#include "base/android/jni_array.h"
-#include "base/android/jni_string.h"
-#include "base/callback_helpers.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/client_certificate_delegate.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/web_contents.h"
-#include "jni/AwContentsClientBridge_jni.h"
-#include "net/cert/x509_certificate.h"
-#include "net/http/http_response_headers.h"
-#include "net/ssl/openssl_client_key_store.h"
-#include "net/ssl/ssl_cert_request_info.h"
-#include "net/ssl/ssl_client_cert_type.h"
-#include "net/ssl/ssl_platform_key_android.h"
-#include "net/ssl/ssl_private_key.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "url/gurl.h"
-
-using base::android::AttachCurrentThread;
-using base::android::ConvertJavaStringToUTF16;
-using base::android::ConvertUTF8ToJavaString;
-using base::android::ConvertUTF16ToJavaString;
-using base::android::HasException;
-using base::android::JavaRef;
-using base::android::ScopedJavaLocalRef;
-using base::android::ToJavaArrayOfStrings;
-using content::BrowserThread;
-using std::vector;
-
-namespace android_webview {
-
-namespace {
-
-// Must be called on the I/O thread to record a client certificate
-// and its private key in the OpenSSLClientKeyStore.
-void RecordClientCertificateKey(net::X509Certificate* client_cert,
- scoped_refptr<net::SSLPrivateKey> private_key) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
- net::OpenSSLClientKeyStore::GetInstance()->RecordClientCertPrivateKey(
- client_cert, std::move(private_key));
-}
-
-} // namespace
-
-AwContentsClientBridge::AwContentsClientBridge(JNIEnv* env,
- const JavaRef<jobject>& obj)
- : java_ref_(env, obj) {
- DCHECK(!obj.is_null());
- Java_AwContentsClientBridge_setNativeContentsClientBridge(
- env, obj, reinterpret_cast<intptr_t>(this));
-}
-
-AwContentsClientBridge::~AwContentsClientBridge() {
- JNIEnv* env = AttachCurrentThread();
-
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (!obj.is_null()) {
- // Clear the weak reference from the java peer to the native object since
- // it is possible that java object lifetime can exceed the AwContens.
- Java_AwContentsClientBridge_setNativeContentsClientBridge(env, obj, 0);
- }
-
- for (IDMap<content::ClientCertificateDelegate*>::iterator iter(
- &pending_client_cert_request_delegates_);
- !iter.IsAtEnd(); iter.Advance()) {
- delete iter.GetCurrentValue();
- }
-}
-
-void AwContentsClientBridge::AllowCertificateError(
- int cert_error,
- net::X509Certificate* cert,
- const GURL& request_url,
- const base::Callback<void(content::CertificateRequestResultType)>& callback,
- bool* cancel_request) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
-
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return;
-
- std::string der_string;
- net::X509Certificate::GetDEREncoded(cert->os_cert_handle(), &der_string);
- ScopedJavaLocalRef<jbyteArray> jcert = base::android::ToJavaByteArray(
- env, reinterpret_cast<const uint8_t*>(der_string.data()),
- der_string.length());
- ScopedJavaLocalRef<jstring> jurl(ConvertUTF8ToJavaString(
- env, request_url.spec()));
- // We need to add the callback before making the call to java side,
- // as it may do a synchronous callback prior to returning.
- int request_id = pending_cert_error_callbacks_.Add(
- base::MakeUnique<CertErrorCallback>(callback));
- *cancel_request = !Java_AwContentsClientBridge_allowCertificateError(
- env, obj, cert_error, jcert, jurl, request_id);
- // if the request is cancelled, then cancel the stored callback
- if (*cancel_request) {
- pending_cert_error_callbacks_.Remove(request_id);
- }
-}
-
-void AwContentsClientBridge::ProceedSslError(JNIEnv* env,
- const JavaRef<jobject>& obj,
- jboolean proceed,
- jint id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- CertErrorCallback* callback = pending_cert_error_callbacks_.Lookup(id);
- if (!callback || callback->is_null()) {
- LOG(WARNING) << "Ignoring unexpected ssl error proceed callback";
- return;
- }
- callback->Run(proceed ? content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE
- : content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL);
- pending_cert_error_callbacks_.Remove(id);
-}
-
-// This method is inspired by SelectClientCertificate() in
-// chrome/browser/ui/android/ssl_client_certificate_request.cc
-void AwContentsClientBridge::SelectClientCertificate(
- net::SSLCertRequestInfo* cert_request_info,
- std::unique_ptr<content::ClientCertificateDelegate> delegate) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // Add the callback to id map.
- int request_id =
- pending_client_cert_request_delegates_.Add(delegate.release());
- // Make sure callback is run on error.
- base::ScopedClosureRunner guard(base::Bind(
- &AwContentsClientBridge::HandleErrorInClientCertificateResponse,
- base::Unretained(this),
- request_id));
-
- JNIEnv* env = base::android::AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return;
-
- // Build the |key_types| JNI parameter, as a String[]
- std::vector<std::string> key_types;
- for (size_t i = 0; i < cert_request_info->cert_key_types.size(); ++i) {
- switch (cert_request_info->cert_key_types[i]) {
- case net::CLIENT_CERT_RSA_SIGN:
- key_types.push_back("RSA");
- break;
- case net::CLIENT_CERT_ECDSA_SIGN:
- key_types.push_back("ECDSA");
- break;
- default:
- // Ignore unknown types.
- break;
- }
- }
-
- ScopedJavaLocalRef<jobjectArray> key_types_ref =
- base::android::ToJavaArrayOfStrings(env, key_types);
- if (key_types_ref.is_null()) {
- LOG(ERROR) << "Could not create key types array (String[])";
- return;
- }
-
- // Build the |encoded_principals| JNI parameter, as a byte[][]
- ScopedJavaLocalRef<jobjectArray> principals_ref =
- base::android::ToJavaArrayOfByteArray(
- env, cert_request_info->cert_authorities);
- if (principals_ref.is_null()) {
- LOG(ERROR) << "Could not create principals array (byte[][])";
- return;
- }
-
- // Build the |host_name| and |port| JNI parameters, as a String and
- // a jint.
- ScopedJavaLocalRef<jstring> host_name_ref =
- base::android::ConvertUTF8ToJavaString(
- env, cert_request_info->host_and_port.host());
-
- Java_AwContentsClientBridge_selectClientCertificate(
- env, obj, request_id, key_types_ref, principals_ref, host_name_ref,
- cert_request_info->host_and_port.port());
-
- // Release the guard.
- ignore_result(guard.Release());
-}
-
-// This method is inspired by OnSystemRequestCompletion() in
-// chrome/browser/ui/android/ssl_client_certificate_request.cc
-void AwContentsClientBridge::ProvideClientCertificateResponse(
- JNIEnv* env,
- const JavaRef<jobject>& obj,
- int request_id,
- const JavaRef<jobjectArray>& encoded_chain_ref,
- const JavaRef<jobject>& private_key_ref) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- content::ClientCertificateDelegate* delegate =
- pending_client_cert_request_delegates_.Lookup(request_id);
- DCHECK(delegate);
-
- if (encoded_chain_ref.is_null() || private_key_ref.is_null()) {
- LOG(ERROR) << "No client certificate selected";
- pending_client_cert_request_delegates_.Remove(request_id);
- delegate->ContinueWithCertificate(nullptr);
- delete delegate;
- return;
- }
-
- // Make sure callback is run on error.
- base::ScopedClosureRunner guard(base::Bind(
- &AwContentsClientBridge::HandleErrorInClientCertificateResponse,
- base::Unretained(this),
- request_id));
-
- // Convert the encoded chain to a vector of strings.
- std::vector<std::string> encoded_chain_strings;
- if (!encoded_chain_ref.is_null()) {
- base::android::JavaArrayOfByteArrayToStringVector(
- env, encoded_chain_ref.obj(), &encoded_chain_strings);
- }
-
- std::vector<base::StringPiece> encoded_chain;
- for (size_t i = 0; i < encoded_chain_strings.size(); ++i)
- encoded_chain.push_back(encoded_chain_strings[i]);
-
- // Create the X509Certificate object from the encoded chain.
- scoped_refptr<net::X509Certificate> client_cert(
- net::X509Certificate::CreateFromDERCertChain(encoded_chain));
- if (!client_cert.get()) {
- LOG(ERROR) << "Could not decode client certificate chain";
- return;
- }
-
- // Create an SSLPrivateKey wrapper for the private key JNI reference.
- scoped_refptr<net::SSLPrivateKey> private_key =
- net::WrapJavaPrivateKey(client_cert.get(), private_key_ref);
- if (!private_key) {
- LOG(ERROR) << "Could not create OpenSSL wrapper for private key";
- return;
- }
-
- // Release the guard and |pending_client_cert_request_delegates_| references
- // to |delegate|.
- pending_client_cert_request_delegates_.Remove(request_id);
- ignore_result(guard.Release());
-
- // RecordClientCertificateKey() must be called on the I/O thread,
- // before the delegate is called with the selected certificate on
- // the UI thread.
- content::BrowserThread::PostTaskAndReply(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&RecordClientCertificateKey, base::RetainedRef(client_cert),
- base::Passed(&private_key)),
- base::Bind(&content::ClientCertificateDelegate::ContinueWithCertificate,
- base::Owned(delegate), base::RetainedRef(client_cert)));
-}
-
-void AwContentsClientBridge::RunJavaScriptDialog(
- content::JavaScriptDialogType dialog_type,
- const GURL& origin_url,
- const base::string16& message_text,
- const base::string16& default_prompt_text,
- const content::JavaScriptDialogManager::DialogClosedCallback& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
-
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null()) {
- callback.Run(false, base::string16());
- return;
- }
-
- int callback_id = pending_js_dialog_callbacks_.Add(
- base::MakeUnique<content::JavaScriptDialogManager::DialogClosedCallback>(
- callback));
- ScopedJavaLocalRef<jstring> jurl(
- ConvertUTF8ToJavaString(env, origin_url.spec()));
- ScopedJavaLocalRef<jstring> jmessage(
- ConvertUTF16ToJavaString(env, message_text));
-
- switch (dialog_type) {
- case content::JAVASCRIPT_DIALOG_TYPE_ALERT: {
- devtools_instrumentation::ScopedEmbedderCallbackTask("onJsAlert");
- Java_AwContentsClientBridge_handleJsAlert(env, obj, jurl, jmessage,
- callback_id);
- break;
- }
- case content::JAVASCRIPT_DIALOG_TYPE_CONFIRM: {
- devtools_instrumentation::ScopedEmbedderCallbackTask("onJsConfirm");
- Java_AwContentsClientBridge_handleJsConfirm(env, obj, jurl, jmessage,
- callback_id);
- break;
- }
- case content::JAVASCRIPT_DIALOG_TYPE_PROMPT: {
- ScopedJavaLocalRef<jstring> jdefault_value(
- ConvertUTF16ToJavaString(env, default_prompt_text));
- devtools_instrumentation::ScopedEmbedderCallbackTask("onJsPrompt");
- Java_AwContentsClientBridge_handleJsPrompt(env, obj, jurl, jmessage,
- jdefault_value, callback_id);
- break;
- }
- default:
- NOTREACHED();
- }
-}
-
-void AwContentsClientBridge::RunBeforeUnloadDialog(
- const GURL& origin_url,
- const content::JavaScriptDialogManager::DialogClosedCallback& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
-
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null()) {
- callback.Run(false, base::string16());
- return;
- }
-
- const base::string16 message_text =
- l10n_util::GetStringUTF16(IDS_BEFOREUNLOAD_MESSAGEBOX_MESSAGE);
-
- int callback_id = pending_js_dialog_callbacks_.Add(
- base::MakeUnique<content::JavaScriptDialogManager::DialogClosedCallback>(
- callback));
- ScopedJavaLocalRef<jstring> jurl(
- ConvertUTF8ToJavaString(env, origin_url.spec()));
- ScopedJavaLocalRef<jstring> jmessage(
- ConvertUTF16ToJavaString(env, message_text));
-
- devtools_instrumentation::ScopedEmbedderCallbackTask("onJsBeforeUnload");
- Java_AwContentsClientBridge_handleJsBeforeUnload(env, obj, jurl, jmessage,
- callback_id);
-}
-
-bool AwContentsClientBridge::ShouldOverrideUrlLoading(const base::string16& url,
- bool has_user_gesture,
- bool is_redirect,
- bool is_main_frame) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return false;
- ScopedJavaLocalRef<jstring> jurl = ConvertUTF16ToJavaString(env, url);
- devtools_instrumentation::ScopedEmbedderCallbackTask(
- "shouldOverrideUrlLoading");
- bool did_override = Java_AwContentsClientBridge_shouldOverrideUrlLoading(
- env, obj, jurl, has_user_gesture, is_redirect, is_main_frame);
- if (HasException(env)) {
- // Tell the chromium message loop to not perform any tasks after the current
- // one - we want to make sure we return to Java cleanly without first making
- // any new JNI calls.
- base::MessageLoopForUI::current()->Abort();
- // If we crashed we don't want to continue the navigation.
- return true;
- }
- return did_override;
-}
-
-void AwContentsClientBridge::NewDownload(const GURL& url,
- const std::string& user_agent,
- const std::string& content_disposition,
- const std::string& mime_type,
- int64_t content_length) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return;
-
- ScopedJavaLocalRef<jstring> jstring_url =
- ConvertUTF8ToJavaString(env, url.spec());
- ScopedJavaLocalRef<jstring> jstring_user_agent =
- ConvertUTF8ToJavaString(env, user_agent);
- ScopedJavaLocalRef<jstring> jstring_content_disposition =
- ConvertUTF8ToJavaString(env, content_disposition);
- ScopedJavaLocalRef<jstring> jstring_mime_type =
- ConvertUTF8ToJavaString(env, mime_type);
-
- Java_AwContentsClientBridge_newDownload(
- env, obj, jstring_url, jstring_user_agent, jstring_content_disposition,
- jstring_mime_type, content_length);
-}
-
-void AwContentsClientBridge::NewLoginRequest(const std::string& realm,
- const std::string& account,
- const std::string& args) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return;
-
- ScopedJavaLocalRef<jstring> jrealm = ConvertUTF8ToJavaString(env, realm);
- ScopedJavaLocalRef<jstring> jargs = ConvertUTF8ToJavaString(env, args);
-
- ScopedJavaLocalRef<jstring> jaccount;
- if (!account.empty())
- jaccount = ConvertUTF8ToJavaString(env, account);
-
- Java_AwContentsClientBridge_newLoginRequest(env, obj, jrealm, jaccount,
- jargs);
-}
-
-void AwContentsClientBridge::OnReceivedError(
- const AwWebResourceRequest& request,
- int error_code) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return;
-
- ScopedJavaLocalRef<jstring> jstring_description =
- ConvertUTF8ToJavaString(env, net::ErrorToString(error_code));
-
- AwWebResourceRequest::AwJavaWebResourceRequest java_web_resource_request;
- AwWebResourceRequest::ConvertToJava(env, request, &java_web_resource_request);
-
- Java_AwContentsClientBridge_onReceivedError(
- env, obj, java_web_resource_request.jurl, request.is_main_frame,
- request.has_user_gesture, java_web_resource_request.jmethod,
- java_web_resource_request.jheader_names,
- java_web_resource_request.jheader_values, error_code,
- jstring_description);
-}
-
-void AwContentsClientBridge::OnReceivedHttpError(
- const AwWebResourceRequest& request,
- const scoped_refptr<const net::HttpResponseHeaders>& response_headers) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
- if (obj.is_null())
- return;
-
- AwWebResourceRequest::AwJavaWebResourceRequest java_web_resource_request;
- AwWebResourceRequest::ConvertToJava(env, request, &java_web_resource_request);
-
- vector<std::string> response_header_names;
- vector<std::string> response_header_values;
-
- {
- size_t headers_iterator = 0;
- std::string header_name, header_value;
- while (response_headers->EnumerateHeaderLines(
- &headers_iterator, &header_name, &header_value)) {
- response_header_names.push_back(header_name);
- response_header_values.push_back(header_value);
- }
- }
-
- std::string mime_type, encoding;
- response_headers->GetMimeTypeAndCharset(&mime_type, &encoding);
- ScopedJavaLocalRef<jstring> jstring_mime_type =
- ConvertUTF8ToJavaString(env, mime_type);
- ScopedJavaLocalRef<jstring> jstring_encoding =
- ConvertUTF8ToJavaString(env, encoding);
- int status_code = response_headers->response_code();
- ScopedJavaLocalRef<jstring> jstring_reason =
- ConvertUTF8ToJavaString(env, response_headers->GetStatusText());
- ScopedJavaLocalRef<jobjectArray> jstringArray_response_header_names =
- ToJavaArrayOfStrings(env, response_header_names);
- ScopedJavaLocalRef<jobjectArray> jstringArray_response_header_values =
- ToJavaArrayOfStrings(env, response_header_values);
-
- Java_AwContentsClientBridge_onReceivedHttpError(
- env, obj, java_web_resource_request.jurl, request.is_main_frame,
- request.has_user_gesture, java_web_resource_request.jmethod,
- java_web_resource_request.jheader_names,
- java_web_resource_request.jheader_values, jstring_mime_type,
- jstring_encoding, status_code, jstring_reason,
- jstringArray_response_header_names, jstringArray_response_header_values);
-}
-
-void AwContentsClientBridge::ConfirmJsResult(JNIEnv* env,
- const JavaRef<jobject>&,
- int id,
- const JavaRef<jstring>& prompt) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- content::JavaScriptDialogManager::DialogClosedCallback* callback =
- pending_js_dialog_callbacks_.Lookup(id);
- if (!callback) {
- LOG(WARNING) << "Unexpected JS dialog confirm. " << id;
- return;
- }
- base::string16 prompt_text;
- if (!prompt.is_null()) {
- prompt_text = ConvertJavaStringToUTF16(env, prompt);
- }
- callback->Run(true, prompt_text);
- pending_js_dialog_callbacks_.Remove(id);
-}
-
-void AwContentsClientBridge::CancelJsResult(JNIEnv*,
- const JavaRef<jobject>&,
- int id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- content::JavaScriptDialogManager::DialogClosedCallback* callback =
- pending_js_dialog_callbacks_.Lookup(id);
- if (!callback) {
- LOG(WARNING) << "Unexpected JS dialog cancel. " << id;
- return;
- }
- callback->Run(false, base::string16());
- pending_js_dialog_callbacks_.Remove(id);
-}
-
-// Use to cleanup if there is an error in client certificate response.
-void AwContentsClientBridge::HandleErrorInClientCertificateResponse(
- int request_id) {
- content::ClientCertificateDelegate* delegate =
- pending_client_cert_request_delegates_.Lookup(request_id);
- pending_client_cert_request_delegates_.Remove(request_id);
-
- delete delegate;
-}
-
-bool RegisterAwContentsClientBridge(JNIEnv* env) {
- return RegisterNativesImpl(env);
-}
-
-} // namespace android_webview

Powered by Google App Engine
This is Rietveld 408576698