summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java33
-rw-r--r--content/browser/android/web_contents_observer_proxy.cc15
-rw-r--r--content/browser/android/web_contents_observer_proxy.h1
3 files changed, 48 insertions, 1 deletions
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java
index 177f8c7..6fb0b3d 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/LoadDataWithBaseUrlTest.java
@@ -373,4 +373,37 @@ public class LoadDataWithBaseUrlTest extends AwTestBase {
assertEquals("true", executeJavaScriptAndWaitForResult(mAwContents, mContentsClient,
"window.gotToEndOfBody"));
}
+
+ @SmallTest
+ @Feature({"AndroidWebView"})
+ public void testOnPageFinishedWhenInterrupted() throws Throwable {
+ // See crbug.com/594001 -- when a javascript: URL is loaded, the pending entry
+ // gets discarded and the previous load goes through a different path
+ // inside NavigationController.
+ final String pageHtml = "<html><body>Hello, world!</body></html>";
+ final String baseUrl = "http://example.com/";
+ final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
+ mContentsClient.getOnPageFinishedHelper();
+ final int callCount = onPageFinishedHelper.getCallCount();
+ loadDataWithBaseUrlAsync(mAwContents, pageHtml, "text/html", false, baseUrl, null);
+ loadUrlAsync(mAwContents, "javascript:42");
+ onPageFinishedHelper.waitForCallback(callCount);
+ assertEquals(baseUrl, onPageFinishedHelper.getUrl());
+ }
+
+ @SmallTest
+ @Feature({"AndroidWebView"})
+ public void testOnPageFinishedWithInvalidBaseUrlWhenInterrupted() throws Throwable {
+ final String pageHtml = CommonResources.ABOUT_HTML;
+ final String invalidBaseUrl = "http://";
+ final TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
+ mContentsClient.getOnPageFinishedHelper();
+ final int callCount = onPageFinishedHelper.getCallCount();
+ getAwSettingsOnUiThread(mAwContents).setJavaScriptEnabled(true);
+ loadDataWithBaseUrlAsync(mAwContents, pageHtml, "text/html", false, invalidBaseUrl, null);
+ loadUrlAsync(mAwContents, "javascript:42");
+ onPageFinishedHelper.waitForCallback(callCount);
+ // Verify that the load succeeds. The actual base url is undefined.
+ assertEquals(CommonResources.ABOUT_TITLE, getTitleOnUiThread(mAwContents));
+ }
}
diff --git a/content/browser/android/web_contents_observer_proxy.cc b/content/browser/android/web_contents_observer_proxy.cc
index 22ab07c..d176f61 100644
--- a/content/browser/android/web_contents_observer_proxy.cc
+++ b/content/browser/android/web_contents_observer_proxy.cc
@@ -81,6 +81,9 @@ void WebContentsObserverProxy::DidStartLoading() {
ScopedJavaLocalRef<jobject> obj(java_observer_);
ScopedJavaLocalRef<jstring> jstring_url(
ConvertUTF8ToJavaString(env, web_contents()->GetVisibleURL().spec()));
+ if (auto entry = web_contents()->GetController().GetPendingEntry()) {
+ base_url_of_last_started_data_url_ = entry->GetBaseURLForDataURL();
+ }
Java_WebContentsObserverProxy_didStartLoading(env, obj.obj(),
jstring_url.obj());
}
@@ -90,6 +93,8 @@ void WebContentsObserverProxy::DidStopLoading() {
ScopedJavaLocalRef<jobject> obj(java_observer_);
std::string url_string = web_contents()->GetLastCommittedURL().spec();
SetToBaseURLForDataURLIfNeeded(&url_string);
+ // DidStopLoading is the last event we should get.
+ base_url_of_last_started_data_url_ = GURL::EmptyGURL();
ScopedJavaLocalRef<jstring> jstring_url(ConvertUTF8ToJavaString(
env, url_string));
Java_WebContentsObserverProxy_didStopLoading(env, obj.obj(),
@@ -304,8 +309,16 @@ void WebContentsObserverProxy::SetToBaseURLForDataURLIfNeeded(
NavigationEntry* entry =
web_contents()->GetController().GetLastCommittedEntry();
// Note that GetBaseURLForDataURL is only used by the Android WebView.
- if (entry && !entry->GetBaseURLForDataURL().is_empty())
+ // FIXME: Should we only return valid specs and "about:blank" for invalid
+ // ones? This may break apps.
+ if (entry && !entry->GetBaseURLForDataURL().is_empty()) {
*url = entry->GetBaseURLForDataURL().possibly_invalid_spec();
+ } else if (!base_url_of_last_started_data_url_.is_empty()) {
+ // NavigationController can lose the pending entry and recreate it without
+ // a base URL if there has been a loadUrl("javascript:...") after
+ // loadDataWithBaseUrl.
+ *url = base_url_of_last_started_data_url_.possibly_invalid_spec();
+ }
}
bool RegisterWebContentsObserverProxy(JNIEnv* env) {
diff --git a/content/browser/android/web_contents_observer_proxy.h b/content/browser/android/web_contents_observer_proxy.h
index 2346405..e22edbb 100644
--- a/content/browser/android/web_contents_observer_proxy.h
+++ b/content/browser/android/web_contents_observer_proxy.h
@@ -83,6 +83,7 @@ class WebContentsObserverProxy : public WebContentsObserver {
bool was_ignored_by_handler);
base::android::ScopedJavaGlobalRef<jobject> java_observer_;
+ GURL base_url_of_last_started_data_url_;
DISALLOW_COPY_AND_ASSIGN(WebContentsObserverProxy);
};