diff options
author | mnaganov <mnaganov@chromium.org> | 2015-03-09 10:18:17 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-09 17:19:10 +0000 |
commit | f0a8ffb2ca988fe7de628620f750ee241e5f5d35 (patch) | |
tree | 89081bd42deaa050eb286bf66bbba22060623aee /android_webview | |
parent | 318afca092085cc5375a6b5547383d78baee3778 (diff) | |
download | chromium_src-f0a8ffb2ca988fe7de628620f750ee241e5f5d35.zip chromium_src-f0a8ffb2ca988fe7de628620f750ee241e5f5d35.tar.gz chromium_src-f0a8ffb2ca988fe7de628620f750ee241e5f5d35.tar.bz2 |
[Android WebView] Lay the groundwork for a better onReceivedError
This patch should not change any behaviour. It introduces a new version
of onReceviedError that will be called for all resources and provides
more information about the failed request.
BUG=456782
Review URL: https://codereview.chromium.org/992593003
Cr-Commit-Position: refs/heads/master@{#319664}
Diffstat (limited to 'android_webview')
7 files changed, 116 insertions, 31 deletions
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java index 8413a71..08b877b 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java @@ -578,6 +578,10 @@ public class WebViewContentsClientAdapter extends AwContentsClient { */ @Override public void onReceivedError(int errorCode, String description, String failingUrl) { + // TODO(mnaganov): In the next version of glue, this will look as follows: + // if (<next-level-api>) return; + // Currently, we should just run this code always. + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.CUR_DEVELOPMENT + 1) return; try { TraceEvent.begin("WebViewContentsClientAdapter.onReceivedError"); if (description == null || description.isEmpty()) { @@ -587,7 +591,35 @@ public class WebViewContentsClientAdapter extends AwContentsClient { description = mWebViewDelegate.getErrorString(mContext, errorCode); } if (TRACE) Log.d(TAG, "onReceivedError=" + failingUrl); - mWebViewClient.onReceivedError(mWebView, errorCode, description, failingUrl); + mWebViewClient.onReceivedError( + mWebView, errorCode, description, failingUrl); + } finally { + TraceEvent.end("WebViewContentsClientAdapter.onReceivedError"); + } + } + + /** + * @see ContentViewClient#onReceivedError( + * AwContentsClient.AwWebResourceRequest,AwContentsClient.AwWebResourceError) + */ + @Override + public void onReceivedError2(AwContentsClient.AwWebResourceRequest request, + AwContentsClient.AwWebResourceError error) { + // TODO(mnaganov): In the next version of glue, this will look as follows: + // if (!<next-level-api>) return; + // Currently, we should never run this code. + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.CUR_DEVELOPMENT + 1) return; + try { + TraceEvent.begin("WebViewContentsClientAdapter.onReceivedError"); + if (error.description == null || error.description.isEmpty()) { + // ErrorStrings is @hidden, so we can't do this in AwContents. Normally the net/ + // layer will set a valid description, but for synthesized callbacks (like in the + // case for intercepted requests) AwContents will pass in null. + error.description = mWebViewDelegate.getErrorString(mContext, error.errorCode); + } + if (TRACE) Log.d(TAG, "onReceivedError=" + request.url); + // TODO(mnaganov): When the new API becomes available, uncomment the following: + // mWebViewClient.onReceivedError(request, error); } finally { TraceEvent.end("WebViewContentsClientAdapter.onReceivedError"); } diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 9384385..6f8fdc7 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java @@ -370,14 +370,14 @@ public class AwContents implements SmartClipProvider, mContentsClient.getCallbackHelper().postOnLoadResource(url); } - if (request.isMainFrame && awWebResourceResponse != null - && awWebResourceResponse.getData() == null) { + if (awWebResourceResponse != null && awWebResourceResponse.getData() == null) { // In this case the intercepted URLRequest job will simulate an empty response // which doesn't trigger the onReceivedError callback. For WebViewClassic // compatibility we synthesize that callback. http://crbug.com/180950 mContentsClient.getCallbackHelper().postOnReceivedError( - ErrorCodeConversionHelper.ERROR_UNKNOWN, - null /* filled in by the glue layer */, url); + request, + /* error description filled in by the glue layer */ + new AwContentsClient.AwWebResourceError()); } return awWebResourceResponse; } diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java index a81b2ed..2b5514b 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java @@ -92,6 +92,14 @@ public abstract class AwContentsClient { public HashMap<String, String> requestHeaders; } + /** + * Parameters for {@link AwContentsClient#onReceivedError} method. + */ + public static class AwWebResourceError { + public int errorCode = ErrorCodeConversionHelper.ERROR_UNKNOWN; + public String description; + } + public abstract void getVisitedHistory(ValueCallback<String[]> callback); public abstract void doUpdateVisitedHistory(String url, boolean isReload); @@ -256,7 +264,33 @@ public abstract class AwContentsClient { public abstract void onPageFinished(String url); - public abstract void onReceivedError(int errorCode, String description, String failingUrl); + public final void onReceivedError(AwWebResourceRequest request, AwWebResourceError error) { + // Only one of these callbacks actually reaches out the client code. The first callback + // is used on API versions up to and including L, the second on subsequent releases. + // Below is the calls diagram: + // + // Old (<= L) glue Old (<= L) android.webkit API + // onReceivedError ---------> onReceivedError + // AwContentsClient onReceivedError2 ->X / + // abs. onReceivedError / + // abs. onReceivedError2 / + // New (M+) glue / New (M+) android.webkit API + // onReceivedError / -> onReceviedError <new> + // "->X" = "do nothing" if (!<M API>) --- / if (isMainFrame) -\ + // else ->X / else ->X | + // onReceivedError2 / V + // if (<M API>) ------- onReceivedError <old> + // else ->X + if (request.isMainFrame) { + onReceivedError(error.errorCode, error.description, request.url); + } + onReceivedError2(request, error); + } + + protected abstract void onReceivedError(int errorCode, String description, String failingUrl); + + protected abstract void onReceivedError2( + AwWebResourceRequest request, AwWebResourceError error); // TODO (michaelbai): Remove this method once the same method remove from // WebViewContentsClientAdapter. diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClientCallbackHelper.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClientCallbackHelper.java index 0744eb4..ac4ba3a 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContentsClientCallbackHelper.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClientCallbackHelper.java @@ -59,14 +59,13 @@ public class AwContentsClientCallbackHelper { } private static class OnReceivedErrorInfo { - final int mErrorCode; - final String mDescription; - final String mFailingUrl; - - OnReceivedErrorInfo(int errorCode, String description, String failingUrl) { - mErrorCode = errorCode; - mDescription = description; - mFailingUrl = failingUrl; + final AwContentsClient.AwWebResourceRequest mRequest; + final AwContentsClient.AwWebResourceError mError; + + OnReceivedErrorInfo(AwContentsClient.AwWebResourceRequest request, + AwContentsClient.AwWebResourceError error) { + mRequest = request; + mError = error; } } @@ -120,8 +119,7 @@ public class AwContentsClientCallbackHelper { } case MSG_ON_RECEIVED_ERROR: { OnReceivedErrorInfo info = (OnReceivedErrorInfo) msg.obj; - mContentsClient.onReceivedError(info.mErrorCode, info.mDescription, - info.mFailingUrl); + mContentsClient.onReceivedError(info.mRequest, info.mError); break; } case MSG_ON_NEW_PICTURE: { @@ -174,8 +172,9 @@ public class AwContentsClientCallbackHelper { mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_RECEIVED_LOGIN_REQUEST, info)); } - public void postOnReceivedError(int errorCode, String description, String failingUrl) { - OnReceivedErrorInfo info = new OnReceivedErrorInfo(errorCode, description, failingUrl); + public void postOnReceivedError(AwContentsClient.AwWebResourceRequest request, + AwContentsClient.AwWebResourceError error) { + OnReceivedErrorInfo info = new OnReceivedErrorInfo(request, error); mHandler.sendMessage(mHandler.obtainMessage(MSG_ON_RECEIVED_ERROR, info)); } diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java index 926d77f..36d0265 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java +++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java @@ -40,18 +40,27 @@ public class AwWebContentsObserver extends WebContentsObserver { String unreachableWebDataUrl = AwContentsStatics.getUnreachableWebDataUrl(); boolean isErrorUrl = unreachableWebDataUrl != null && unreachableWebDataUrl.equals(failingUrl); - if (isMainFrame && !isErrorUrl) { - if (errorCode != NetError.ERR_ABORTED) { - // This error code is generated for the following reasons: - // - WebView.stopLoading is called, - // - the navigation is intercepted by the embedder via shouldOverrideNavigation. - // - // The Android WebView does not notify the embedder of these situations using - // this error code with the WebViewClient.onReceivedError callback. - mAwContentsClient.onReceivedError( - ErrorCodeConversionHelper.convertErrorCode(errorCode), description, - failingUrl); - } + if (isErrorUrl) return; + if (errorCode != NetError.ERR_ABORTED) { + // This error code is generated for the following reasons: + // - WebView.stopLoading is called, + // - the navigation is intercepted by the embedder via shouldOverrideNavigation. + // + // The Android WebView does not notify the embedder of these situations using + // this error code with the WebViewClient.onReceivedError callback. + AwContentsClient.AwWebResourceRequest request = + new AwContentsClient.AwWebResourceRequest(); + request.url = failingUrl; + request.isMainFrame = isMainFrame; + // TODO(mnaganov): Fill in the rest of AwWebResourceRequest fields. Probably, + // we will have to actually invoke the error callback from the network delegate + // in order to catch load errors for all resources. + AwContentsClient.AwWebResourceError error = new AwContentsClient.AwWebResourceError(); + error.errorCode = ErrorCodeConversionHelper.convertErrorCode(errorCode); + error.description = description; + mAwContentsClient.onReceivedError(request, error); + } + if (isMainFrame) { // Need to call onPageFinished after onReceivedError (if there is an error) for // backwards compatibility with the classic webview. mAwContentsClient.onPageFinished(failingUrl); diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java index 7fa242e..de9eb40 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientCallbackHelperTest.java @@ -10,6 +10,7 @@ import android.os.Handler; import android.os.Looper; import android.test.suitebuilder.annotation.SmallTest; +import org.chromium.android_webview.AwContentsClient; import org.chromium.android_webview.AwContentsClientCallbackHelper; import org.chromium.android_webview.test.TestAwContentsClient.OnDownloadStartHelper; import org.chromium.android_webview.test.TestAwContentsClient.OnReceivedLoginRequestHelper; @@ -203,7 +204,13 @@ public class AwContentsClientCallbackHelperTest extends AwTestBase { mContentsClient.getOnReceivedErrorHelper(); int onReceivedErrorCount = receivedErrorHelper.getCallCount(); - mClientHelper.postOnReceivedError(ERROR_CODE, ERROR_MESSAGE, TEST_URL); + AwContentsClient.AwWebResourceRequest request = new AwContentsClient.AwWebResourceRequest(); + request.url = TEST_URL; + request.isMainFrame = true; + AwContentsClient.AwWebResourceError error = new AwContentsClient.AwWebResourceError(); + error.errorCode = ERROR_CODE; + error.description = ERROR_MESSAGE; + mClientHelper.postOnReceivedError(request, error); receivedErrorHelper.waitForCallback(onReceivedErrorCount); assertEquals(ERROR_CODE, receivedErrorHelper.getErrorCode()); assertEquals(ERROR_MESSAGE, receivedErrorHelper.getDescription()); diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java b/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java index dd3359e..035ff4c 100644 --- a/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java +++ b/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java @@ -163,6 +163,10 @@ public class NullContentsClient extends AwContentsClient { } @Override + public void onReceivedError2(AwWebResourceRequest request, AwWebResourceError error) { + } + + @Override public void onFormResubmission(Message dontResend, Message resend) { dontResend.sendToTarget(); } |