Commit 0781d318 authored by boliu's avatar boliu Committed by Commit bot

Revert of Move onReceivedError and onReceivedHttpError out of...

Revert of Move onReceivedError and onReceivedHttpError out of AwContentsIoThreadClientImpl (patchset #7 id:120001 of https://codereview.chromium.org/2558223002/ )

Reason for revert:
BUG=673736

Original issue's description:
> Move onReceivedError and onReceivedHttpError out of AwContentsIoThreadClientImpl
>
> Move onReceivedError and onReceivedHttpError out of AwContentsIoThreadClientImpl to AwContentsClientBridge. This is a continuation of the work started in
> https://codereview.chromium.org/2425423004/ and is the third patch.
>
> BUG=645983
>
> Committed: https://crrev.com/f199141ef70d76697647830f498b25706c0b0d0a
> Cr-Commit-Position: refs/heads/master@{#437688}

TBR=sgurun@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=645983

Review-Url: https://codereview.chromium.org/2567043003
Cr-Commit-Position: refs/heads/master@{#438221}
parent 689d5629
......@@ -396,8 +396,6 @@ source_set("common") {
"browser/net/aw_url_request_context_getter.h",
"browser/net/aw_url_request_job_factory.cc",
"browser/net/aw_url_request_job_factory.h",
"browser/net/aw_web_resource_request.cc",
"browser/net/aw_web_resource_request.h",
"browser/net/aw_web_resource_response.h",
"browser/net/init_native_callback.h",
"browser/net/input_stream_reader.cc",
......
......@@ -7,12 +7,10 @@
#include <memory>
#include "android_webview/browser/net/aw_web_resource_request.h"
#include "base/supports_user_data.h"
#include "content/public/browser/certificate_request_result_type.h"
#include "content/public/browser/javascript_dialog_manager.h"
#include "content/public/browser/resource_request_info.h"
#include "net/http/http_response_headers.h"
class GURL;
......@@ -89,17 +87,6 @@ class AwContentsClientBridgeBase {
virtual void NewLoginRequest(const std::string& realm,
const std::string& account,
const std::string& args) = 0;
// Called when a resource loading error has occured (e.g. an I/O error,
// host name lookup failure etc.)
virtual void OnReceivedError(const AwWebResourceRequest& request,
int error_code) = 0;
// Called when a response from the server is received with status code >= 400.
virtual void OnReceivedHttpError(
const AwWebResourceRequest& request,
const scoped_refptr<const net::HttpResponseHeaders>&
response_headers) = 0;
};
} // namespace android_webview
......
......@@ -13,6 +13,7 @@
#include "base/callback_forward.h"
namespace net {
class HttpResponseHeaders;
class URLRequest;
}
......@@ -94,6 +95,15 @@ class AwContentsIoThreadClient {
// Retrieve the AcceptThirdPartyCookies setting value of this AwContents.
virtual bool ShouldAcceptThirdPartyCookies() const = 0;
// Called when a resource loading error has occured (e.g. an I/O error,
// host name lookup failure etc.)
virtual void OnReceivedError(const net::URLRequest* request) = 0;
// Called when a response from the server is received with status code >= 400.
virtual void OnReceivedHttpError(
const net::URLRequest* request,
const net::HttpResponseHeaders* response_headers) = 0;
};
} // namespace android_webview
......
......@@ -5,10 +5,8 @@
#include "android_webview/browser/net/aw_network_delegate.h"
#include "android_webview/browser/aw_browser_context.h"
#include "android_webview/browser/aw_contents_client_bridge_base.h"
#include "android_webview/browser/aw_contents_io_thread_client.h"
#include "android_webview/browser/aw_cookie_access_policy.h"
#include "android_webview/browser/net/aw_web_resource_request.h"
#include "base/android/build_info.h"
#include "components/policy/core/browser/url_blacklist_manager.h"
#include "content/public/browser/browser_thread.h"
......@@ -24,21 +22,6 @@ using content::BrowserThread;
namespace android_webview {
namespace {
void OnReceivedHttpErrorOnUiThread(
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
const AwWebResourceRequest& request,
scoped_refptr<const net::HttpResponseHeaders> original_response_headers) {
AwContentsClientBridgeBase* client =
AwContentsClientBridgeBase::FromWebContentsGetter(web_contents_getter);
if (!client)
return;
client->OnReceivedHttpError(request, original_response_headers);
}
} // namespace
AwNetworkDelegate::AwNetworkDelegate() : url_blacklist_manager_(nullptr) {
}
......@@ -81,17 +64,15 @@ int AwNetworkDelegate::OnHeadersReceived(
scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
GURL* allowed_unsafe_redirect_url) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (original_response_headers->response_code() >= 400) {
const content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(request);
// keep a ref before binding and posting to UI thread.
scoped_refptr<const net::HttpResponseHeaders> response_headers(
original_response_headers);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&OnReceivedHttpErrorOnUiThread,
request_info->GetWebContentsGetterForRequest(),
AwWebResourceRequest(*request), response_headers));
int render_process_id, render_frame_id;
if (original_response_headers->response_code() >= 400 &&
content::ResourceRequestInfo::GetRenderFrameForRequest(
request, &render_process_id, &render_frame_id)) {
std::unique_ptr<AwContentsIoThreadClient> io_thread_client =
AwContentsIoThreadClient::FromID(render_process_id, render_frame_id);
if (io_thread_client.get()) {
io_thread_client->OnReceivedHttpError(request, original_response_headers);
}
}
return net::OK;
}
......
// Copyright 2016 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/browser/net/aw_web_resource_request.h"
#include "content/public/browser/resource_request_info.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF8ToJavaString;
using base::android::ConvertUTF16ToJavaString;
using base::android::ToJavaArrayOfStrings;
namespace android_webview {
AwWebResourceRequest::AwWebResourceRequest(const net::URLRequest& request)
: url(request.url().spec()), method(request.method()) {
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(&request);
is_main_frame =
info && info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME;
has_user_gesture = info && info->HasUserGesture();
net::HttpRequestHeaders headers;
if (!request.GetFullRequestHeaders(&headers))
headers = request.extra_request_headers();
net::HttpRequestHeaders::Iterator headers_iterator(headers);
while (headers_iterator.GetNext()) {
header_names.push_back(headers_iterator.name());
header_values.push_back(headers_iterator.value());
}
}
AwWebResourceRequest::AwWebResourceRequest(AwWebResourceRequest&& other) =
default;
AwWebResourceRequest& AwWebResourceRequest::operator=(
AwWebResourceRequest&& other) = default;
AwWebResourceRequest::~AwWebResourceRequest() = default;
AwWebResourceRequest::AwJavaWebResourceRequest::AwJavaWebResourceRequest() =
default;
AwWebResourceRequest::AwJavaWebResourceRequest::~AwJavaWebResourceRequest() =
default;
// static
void AwWebResourceRequest::ConvertToJava(JNIEnv* env,
const AwWebResourceRequest& request,
AwJavaWebResourceRequest* jRequest) {
jRequest->jurl = ConvertUTF8ToJavaString(env, request.url);
jRequest->jmethod = ConvertUTF8ToJavaString(env, request.method);
jRequest->jheader_names = ToJavaArrayOfStrings(env, request.header_names);
jRequest->jheader_values = ToJavaArrayOfStrings(env, request.header_values);
}
} // namespace android_webview
// Copyright 2016 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.
#ifndef ANDROID_WEBVIEW_BROWSER_NET_AW_WEB_RESOURCE_REQUEST_H_
#define ANDROID_WEBVIEW_BROWSER_NET_AW_WEB_RESOURCE_REQUEST_H_
#include <string>
#include <vector>
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
namespace net {
class URLRequest;
}
namespace android_webview {
// A passive data structure only used to carry request information. This
// class should be copyable.
struct AwWebResourceRequest final {
explicit AwWebResourceRequest(const net::URLRequest& request);
// Add default copy/move/assign operators. Adding explicit destructor
// prevents generating move operator.
AwWebResourceRequest(AwWebResourceRequest&& other);
AwWebResourceRequest& operator=(AwWebResourceRequest&& other);
~AwWebResourceRequest();
// The java equivalent
struct AwJavaWebResourceRequest {
AwJavaWebResourceRequest();
~AwJavaWebResourceRequest();
base::android::ScopedJavaLocalRef<jstring> jurl;
base::android::ScopedJavaLocalRef<jstring> jmethod;
base::android::ScopedJavaLocalRef<jobjectArray> jheader_names;
base::android::ScopedJavaLocalRef<jobjectArray> jheader_values;
};
// Convenience method to convert AwWebResourceRequest to Java equivalent.
static void ConvertToJava(JNIEnv* env,
const AwWebResourceRequest& request,
AwJavaWebResourceRequest* jRequest);
std::string url;
std::string method;
bool is_main_frame;
bool has_user_gesture;
std::vector<std::string> header_names;
std::vector<std::string> header_values;
};
} // namespace android_webview
#endif // ANDROID_WEBVIEW_BROWSER_NET_AW_WEB_RESOURCE_REQUEST_H_
......@@ -12,7 +12,6 @@
#include "android_webview/browser/aw_contents_io_thread_client.h"
#include "android_webview/browser/aw_login_delegate.h"
#include "android_webview/browser/aw_resource_context.h"
#include "android_webview/browser/net/aw_web_resource_request.h"
#include "android_webview/browser/renderer_host/auto_login_parser.h"
#include "android_webview/common/url_constants.h"
#include "base/memory/scoped_vector.h"
......@@ -33,7 +32,6 @@
using android_webview::AwContentsIoThreadClient;
using android_webview::AwContentsClientBridgeBase;
using android_webview::AwWebResourceRequest;
using content::BrowserThread;
using content::ResourceType;
using content::WebContents;
......@@ -86,20 +84,6 @@ void NewLoginRequestOnUIThread(
client->NewLoginRequest(realm, account, args);
}
void OnReceivedErrorOnUiThread(
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
const AwWebResourceRequest& request,
int error_code) {
AwContentsClientBridgeBase* client =
AwContentsClientBridgeBase::FromWebContentsGetter(web_contents_getter);
if (!client) {
DLOG(WARNING) << "io_client is null, onReceivedError dropped for "
<< request.url;
return;
}
client->OnReceivedError(request, error_code);
}
} // namespace
namespace android_webview {
......@@ -301,15 +285,19 @@ void AwResourceDispatcherHostDelegate::RequestComplete(
if (request && !request->status().is_success()) {
const content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(request);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&OnReceivedErrorOnUiThread,
request_info->GetWebContentsGetterForRequest(),
AwWebResourceRequest(*request), request->status().error()));
std::unique_ptr<AwContentsIoThreadClient> io_client =
AwContentsIoThreadClient::FromID(request_info->GetChildID(),
request_info->GetRenderFrameID());
if (io_client) {
io_client->OnReceivedError(request);
} else {
DLOG(WARNING) << "io_client is null, onReceivedError dropped for " <<
request->url();
}
}
}
void AwResourceDispatcherHostDelegate::DownloadStarting(
net::URLRequest* request,
content::ResourceContext* resource_context,
......
......@@ -73,6 +73,7 @@ import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.navigation_controller.LoadURLType;
import org.chromium.content_public.browser.navigation_controller.UserAgentOverrideOption;
import org.chromium.content_public.common.Referrer;
import org.chromium.net.NetError;
import org.chromium.net.NetworkChangeNotifier;
import org.chromium.ui.base.ActivityWindowAndroid;
import org.chromium.ui.base.PageTransition;
......@@ -470,6 +471,37 @@ public class AwContents implements SmartClipProvider, PostMessageSender.PostMess
public boolean shouldAcceptThirdPartyCookies() {
return mSettings.getAcceptThirdPartyCookies();
}
@Override
public void onReceivedError(AwContentsClient.AwWebResourceRequest request,
AwContentsClient.AwWebResourceError error) {
String unreachableWebDataUrl = AwContentsStatics.getUnreachableWebDataUrl();
boolean isErrorUrl =
unreachableWebDataUrl != null && unreachableWebDataUrl.equals(request.url);
if (!isErrorUrl && error.errorCode != NetError.ERR_ABORTED) {
// NetError.ERR_ABORTED error code is generated for the following reasons:
// - WebView.stopLoading is called;
// - the navigation is intercepted by the embedder via shouldOverrideUrlLoading;
// - server returned 204 status (no content).
//
// Android WebView does not notify the embedder of these situations using
// this error code with the WebViewClient.onReceivedError callback.
error.errorCode = ErrorCodeConversionHelper.convertErrorCode(error.errorCode);
mContentsClient.getCallbackHelper().postOnReceivedError(request, error);
if (request.isMainFrame) {
// Need to call onPageFinished after onReceivedError for backwards compatibility
// with the classic webview. See also AwWebContentsObserver.didFailLoad which is
// used when we want to send onPageFinished alone.
mContentsClient.getCallbackHelper().postOnPageFinished(request.url);
}
}
}
@Override
public void onReceivedHttpError(AwContentsClient.AwWebResourceRequest request,
AwWebResourceResponse response) {
mContentsClient.getCallbackHelper().postOnReceivedHttpError(request, response);
}
}
private class BackgroundThreadClientImpl extends AwContentsBackgroundThreadClient {
......
......@@ -14,14 +14,11 @@ import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.CalledByNativeUnchecked;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.net.NetError;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
......@@ -262,90 +259,10 @@ public class AwContentsClientBridge {
}
@CalledByNative
private void newLoginRequest(String realm, String account, String args) {
public void newLoginRequest(String realm, String account, String args) {
mClient.getCallbackHelper().postOnReceivedLoginRequest(realm, account, args);
}
@CalledByNative
private void onReceivedError(
// WebResourceRequest
String url, boolean isMainFrame, boolean hasUserGesture, String method,
String[] requestHeaderNames, String[] requestHeaderValues,
// WebResourceError
int errorCode, String description) {
AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest();
request.url = url;
request.isMainFrame = isMainFrame;
request.hasUserGesture = hasUserGesture;
request.method = method;
request.requestHeaders = new HashMap<String, String>(requestHeaderNames.length);
for (int i = 0; i < requestHeaderNames.length; ++i) {
request.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
}
AwContentsClient.AwWebResourceError error = new AwContentsClient.AwWebResourceError();
error.errorCode = errorCode;
error.description = description;
String unreachableWebDataUrl = AwContentsStatics.getUnreachableWebDataUrl();
boolean isErrorUrl =
unreachableWebDataUrl != null && unreachableWebDataUrl.equals(request.url);
if (!isErrorUrl && error.errorCode != NetError.ERR_ABORTED) {
// NetError.ERR_ABORTED error code is generated for the following reasons:
// - WebView.stopLoading is called;
// - the navigation is intercepted by the embedder via shouldOverrideUrlLoading;
// - server returned 204 status (no content).
//
// Android WebView does not notify the embedder of these situations using
// this error code with the WebViewClient.onReceivedError callback.
error.errorCode = ErrorCodeConversionHelper.convertErrorCode(error.errorCode);
mClient.getCallbackHelper().postOnReceivedError(request, error);
if (request.isMainFrame) {
// Need to call onPageFinished after onReceivedError for backwards compatibility
// with the classic webview. See also AwWebContentsObserver.didFailLoad which is
// used when we want to send onPageFinished alone.
mClient.getCallbackHelper().postOnPageFinished(request.url);
}
}
}
@CalledByNative
private void onReceivedHttpError(
// WebResourceRequest
String url, boolean isMainFrame, boolean hasUserGesture, String method,
String[] requestHeaderNames, String[] requestHeaderValues,
// WebResourceResponse
String mimeType, String encoding, int statusCode, String reasonPhrase,
String[] responseHeaderNames, String[] responseHeaderValues) {
AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest();
request.url = url;
request.isMainFrame = isMainFrame;
request.hasUserGesture = hasUserGesture;
request.method = method;
request.requestHeaders = new HashMap<String, String>(requestHeaderNames.length);
for (int i = 0; i < requestHeaderNames.length; ++i) {
request.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
}
Map<String, String> responseHeaders =
new HashMap<String, String>(responseHeaderNames.length);
// Note that we receive un-coalesced response header lines, thus we need to combine
// values for the same header.
for (int i = 0; i < responseHeaderNames.length; ++i) {
if (!responseHeaders.containsKey(responseHeaderNames[i])) {
responseHeaders.put(responseHeaderNames[i], responseHeaderValues[i]);
} else if (!responseHeaderValues[i].isEmpty()) {
String currentValue = responseHeaders.get(responseHeaderNames[i]);
if (!currentValue.isEmpty()) {
currentValue += ", ";
}
responseHeaders.put(responseHeaderNames[i], currentValue + responseHeaderValues[i]);
}
}
AwWebResourceResponse response = new AwWebResourceResponse(
mimeType, encoding, null, statusCode, reasonPhrase, responseHeaders);
mClient.getCallbackHelper().postOnReceivedHttpError(request, response);
}
@CalledByNativeUnchecked
private boolean shouldOverrideUrlLoading(
String url, boolean hasUserGesture, boolean isRedirect, boolean isMainFrame) {
......
......@@ -7,6 +7,9 @@ package org.chromium.android_webview;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import java.util.HashMap;
import java.util.Map;
/**
* Delegate for handling callbacks. All methods are called on the IO thread.
*
......@@ -32,4 +35,73 @@ public abstract class AwContentsIoThreadClient {
@CalledByNative
public abstract AwContentsBackgroundThreadClient getBackgroundThreadClient();
public abstract void onReceivedError(AwContentsClient.AwWebResourceRequest request,
AwContentsClient.AwWebResourceError error);
public abstract void onReceivedHttpError(AwContentsClient.AwWebResourceRequest request,
AwWebResourceResponse response);
// Protected methods ---------------------------------------------------------------------------
@CalledByNative
protected void onReceivedError(
// WebResourceRequest
String url, boolean isMainFrame, boolean hasUserGesture, String method,
String[] requestHeaderNames, String[] requestHeaderValues,
// WebResourceError
int errorCode, String description) {
AwContentsClient.AwWebResourceRequest request =
new AwContentsClient.AwWebResourceRequest();
request.url = url;
request.isMainFrame = isMainFrame;
request.hasUserGesture = hasUserGesture;
request.method = method;
request.requestHeaders = new HashMap<String, String>(requestHeaderNames.length);
for (int i = 0; i < requestHeaderNames.length; ++i) {
request.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
}
AwContentsClient.AwWebResourceError error = new AwContentsClient.AwWebResourceError();
error.errorCode = errorCode;
error.description = description;
onReceivedError(request, error);
}
@CalledByNative
protected void onReceivedHttpError(
// WebResourceRequest
String url, boolean isMainFrame, boolean hasUserGesture, String method,
String[] requestHeaderNames, String[] requestHeaderValues,
// WebResourceResponse
String mimeType, String encoding, int statusCode, String reasonPhrase,
String[] responseHeaderNames, String[] responseHeaderValues) {
AwContentsClient.AwWebResourceRequest request =
new AwContentsClient.AwWebResourceRequest();
request.url = url;
request.isMainFrame = isMainFrame;
request.hasUserGesture = hasUserGesture;
request.method = method;
request.requestHeaders = new HashMap<String, String>(requestHeaderNames.length);
for (int i = 0; i < requestHeaderNames.length; ++i) {
request.requestHeaders.put(requestHeaderNames[i], requestHeaderValues[i]);
}
Map<String, String> responseHeaders =
new HashMap<String, String>(responseHeaderNames.length);
// Note that we receive un-coalesced response header lines, thus we need to combine
// values for the same header.
for (int i = 0; i < responseHeaderNames.length; ++i) {
if (!responseHeaders.containsKey(responseHeaderNames[i])) {
responseHeaders.put(responseHeaderNames[i], responseHeaderValues[i]);
} else if (!responseHeaderValues[i].isEmpty()) {
String currentValue = responseHeaders.get(responseHeaderNames[i]);
if (!currentValue.isEmpty()) {
currentValue += ", ";
}
responseHeaders.put(responseHeaderNames[i], currentValue + responseHeaderValues[i]);
}
}
AwWebResourceResponse response = new AwWebResourceResponse(
mimeType, encoding, null, statusCode, reasonPhrase, responseHeaders);
onReceivedHttpError(request, response);
}
}
......@@ -81,6 +81,18 @@ public class AwServiceWorkerController {
// see e.g. AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies.
return false;
}
@Override
public void onReceivedError(AwContentsClient.AwWebResourceRequest request,
AwContentsClient.AwWebResourceError error) {
// TODO
}
@Override
public void onReceivedHttpError(AwContentsClient.AwWebResourceRequest request,
AwWebResourceResponse response) {
// TODO
}
}
private class ServiceWorkerBackgroundThreadClientImpl
......
......@@ -23,7 +23,6 @@
#include "grit/components_strings.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"
......@@ -39,9 +38,7 @@ 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 {
......@@ -414,77 +411,6 @@ void AwContentsClientBridge::NewLoginRequest(const std::string& realm,
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,
......
......@@ -71,13 +71,6 @@ class AwContentsClientBridge : public AwContentsClientBridgeBase {
const std::string& account,
const std::string& args) override;
void OnReceivedError(const AwWebResourceRequest& request,
int error_code) override;
void OnReceivedHttpError(const AwWebResourceRequest& request,
const scoped_refptr<const net::HttpResponseHeaders>&
response_headers) override;
// Methods called from Java.
void ProceedSslError(JNIEnv* env,
const base::android::JavaRef<jobject>& obj,
......
......@@ -8,7 +8,6 @@
#include <memory>
#include <utility>
#include "android_webview/browser/net/aw_web_resource_request.h"
#include "android_webview/common/devtools_instrumentation.h"
#include "android_webview/native/aw_contents_background_thread_client.h"
#include "android_webview/native/aw_web_resource_response_impl.h"
......@@ -25,7 +24,11 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "jni/AwContentsIoThreadClient_jni.h"
#include "net/base/net_errors.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"
using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
......@@ -40,6 +43,7 @@ using content::WebContents;
using std::map;
using std::pair;
using std::string;
using std::vector;
namespace android_webview {
......@@ -154,6 +158,51 @@ void ClientMapEntryUpdater::WebContentsDestroyed() {
delete this;
}
struct WebResourceRequest {
std::string url;
std::string method;
bool is_main_frame;
bool has_user_gesture;
vector<string> header_names;
vector<string> header_values;
ScopedJavaLocalRef<jstring> jstring_url;
ScopedJavaLocalRef<jstring> jstring_method;
ScopedJavaLocalRef<jobjectArray> jstringArray_header_names;
ScopedJavaLocalRef<jobjectArray> jstringArray_header_values;
WebResourceRequest(const net::URLRequest* request)
: url(request->url().spec()),
method(request->method()) {
const content::ResourceRequestInfo* info =
content::ResourceRequestInfo::ForRequest(request);
is_main_frame =
info && info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME;
has_user_gesture = info && info->HasUserGesture();
net::HttpRequestHeaders headers;
if (!request->GetFullRequestHeaders(&headers))
headers = request->extra_request_headers();
net::HttpRequestHeaders::Iterator headers_iterator(headers);
while (headers_iterator.GetNext()) {
header_names.push_back(headers_iterator.name());
header_values.push_back(headers_iterator.value());
}
}
WebResourceRequest(JNIEnv* env, const net::URLRequest* request)
: WebResourceRequest(request) {
ConvertToJava(env);
}
void ConvertToJava(JNIEnv* env) {
jstring_url = ConvertUTF8ToJavaString(env, url);
jstring_method = ConvertUTF8ToJavaString(env, method);
jstringArray_header_names = ToJavaArrayOfStrings(env, header_names);
jstringArray_header_values = ToJavaArrayOfStrings(env, header_values);
}
};
} // namespace
// AwContentsIoThreadClientImpl -----------------------------------------------
......@@ -264,7 +313,7 @@ AwContentsIoThreadClientImpl::GetCacheMode() const {
namespace {
std::unique_ptr<AwWebResourceResponse> RunShouldInterceptRequest(
const AwWebResourceRequest& request,
WebResourceRequest web_request,
JavaObjectWeakGlobalRef ref) {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
JNIEnv* env = AttachCurrentThread();
......@@ -272,17 +321,16 @@ std::unique_ptr<AwWebResourceResponse> RunShouldInterceptRequest(
if (obj.is_null())
return nullptr;
AwWebResourceRequest::AwJavaWebResourceRequest java_web_resource_request;
AwWebResourceRequest::ConvertToJava(env, request, &java_web_resource_request);
web_request.ConvertToJava(env);
devtools_instrumentation::ScopedEmbedderCallbackTask embedder_callback(
"shouldInterceptRequest");
ScopedJavaLocalRef<jobject> ret =
AwContentsBackgroundThreadClient::shouldInterceptRequest(
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);
env, obj, web_request.jstring_url, web_request.is_main_frame,
web_request.has_user_gesture, web_request.jstring_method,
web_request.jstringArray_header_names,
web_request.jstringArray_header_values);
return std::unique_ptr<AwWebResourceResponse>(
ret.is_null() ? nullptr : new AwWebResourceResponseImpl(ret));
}
......@@ -307,7 +355,7 @@ void AwContentsIoThreadClientImpl::ShouldInterceptRequestAsync(
}
if (!bg_thread_client_object_.is_null()) {
get_response = base::Bind(
&RunShouldInterceptRequest, AwWebResourceRequest(*request),
&RunShouldInterceptRequest, WebResourceRequest(request),
JavaObjectWeakGlobalRef(env, bg_thread_client_object_.obj()));
}
BrowserThread::PostTaskAndReplyWithResult(BrowserThread::FILE, FROM_HERE,
......@@ -353,4 +401,69 @@ bool AwContentsIoThreadClientImpl::ShouldBlockNetworkLoads() const {
java_object_);
}
void AwContentsIoThreadClientImpl::OnReceivedError(
const net::URLRequest* request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (java_object_.is_null())
return;
JNIEnv* env = AttachCurrentThread();
WebResourceRequest web_request(env, request);
int error_code = request->status().error();
ScopedJavaLocalRef<jstring> jstring_description = ConvertUTF8ToJavaString(
env, net::ErrorToString(request->status().error()));
Java_AwContentsIoThreadClient_onReceivedError(
env, java_object_, web_request.jstring_url, web_request.is_main_frame,
web_request.has_user_gesture, web_request.jstring_method,
web_request.jstringArray_header_names,
web_request.jstringArray_header_values, error_code, jstring_description);
}
void AwContentsIoThreadClientImpl::OnReceivedHttpError(
const net::URLRequest* request,
const net::HttpResponseHeaders* response_headers) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (java_object_.is_null())
return;
JNIEnv* env = AttachCurrentThread();
WebResourceRequest web_request(env, request);
vector<string> response_header_names;
vector<string> response_header_values;
{
size_t headers_iterator = 0;
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);
}
}
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_AwContentsIoThreadClient_onReceivedHttpError(
env, java_object_, web_request.jstring_url, web_request.is_main_frame,
web_request.has_user_gesture, web_request.jstring_method,
web_request.jstringArray_header_names,
web_request.jstringArray_header_values, jstring_mime_type,
jstring_encoding, status_code, jstring_reason,
jstringArray_response_header_names, jstringArray_response_header_values);
}
} // namespace android_webview
......@@ -55,6 +55,10 @@ class AwContentsIoThreadClientImpl : public AwContentsIoThreadClient {
bool ShouldBlockFileUrls() const override;
bool ShouldAcceptThirdPartyCookies() const override;
bool ShouldBlockNetworkLoads() const override;
void OnReceivedError(const net::URLRequest* request) override;
void OnReceivedHttpError(
const net::URLRequest* request,
const net::HttpResponseHeaders* response_headers) override;
private:
bool pending_association_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment