summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Naganov <mnaganov@google.com>2015-03-24 11:47:08 +0000
committerMikhail Naganov <mnaganov@google.com>2015-03-24 11:47:08 +0000
commit520a78add2f25f45f5a30ef087b9a6cb3d130776 (patch)
tree7242a5609f5ba4bc0570fcbbe3fb169cd434e1e3
parent1cf285d3a90e0da7d28f7e73651391f212d2a4a8 (diff)
downloadchromium_org-ub-webview-m40-release.tar.gz
Cherry-pick "[Android WebView] Provide user-initiated provisional load detection"webview-m40_r4ub-webview-m40-release
Original CL: https://crrev.com/7a3234c9a19a38726a4a984ff12e2b406423c1d3 Original description: [Android WebView] Provide user-initiated provisional load detection Do not synthesize page loading events on DOM modification, if the provisional load has been started from the API side. It appears that a lot of apps tend to use the following scenario: webView.loadUrl(...); webView.loadUrl('javascript:...'); Which was triggering page loading events to be emitted. This scenario is dubious, as no one guarantees that loading will actually finish prior to executing javascript. But for compatibility reasons we must take it into account and not emit page loading events for "about:blank", as it seems that some apps do unexpected things when they receive it. BUG=458569,469099 Note that this patch also contains bits from this commit required for changes in AwWebContentsObserver to work: https://crrev.com/5668d12d29ab659ad01dc0e0ffdf24f2eb5f187a Bug: 19729876 Change-Id: I12c9610a13a382d725cc9a14fcb9879c92f1f461
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java4
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java25
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java3
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java26
-rw-r--r--chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java8
-rw-r--r--content/browser/frame_host/navigation_controller_android.cc3
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java4
-rw-r--r--content/public/android/java/src/org/chromium/content_public/browser/NavigationEntry.java8
8 files changed, 50 insertions, 31 deletions
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 b7b30b1f35..1a04448977 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -833,7 +833,7 @@ public class AwContents implements SmartClipProvider {
if (mWebContentsObserver != null) {
mWebContentsObserver.detachFromWebContents();
}
- mWebContentsObserver = new AwWebContentsObserver(mWebContents, mContentsClient);
+ mWebContentsObserver = new AwWebContentsObserver(mWebContents, this, mContentsClient);
}
/**
@@ -2012,7 +2012,7 @@ public class AwContents implements SmartClipProvider {
public boolean getDidAttemptLoad() {
if (mDidAttemptLoad) return mDidAttemptLoad;
- mDidAttemptLoad = mWebContentsObserver.hasStartedAnyProvisionalLoad();
+ mDidAttemptLoad = mWebContentsObserver.hasStartedNonApiProvisionalLoadInMainFrame();
return mDidAttemptLoad;
}
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 cd45eadac2..bf012805bc 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
@@ -5,23 +5,30 @@
package org.chromium.android_webview;
import org.chromium.content.browser.WebContentsObserver;
+import org.chromium.content_public.browser.NavigationEntry;
import org.chromium.content_public.browser.WebContents;
import org.chromium.net.NetError;
+import org.chromium.ui.base.PageTransition;
+
+import java.lang.ref.WeakReference;
/**
* Routes notifications from WebContents to AwContentsClient and other listeners.
*/
public class AwWebContentsObserver extends WebContentsObserver {
+ private final WeakReference<AwContents> mAwContents;
private final AwContentsClient mAwContentsClient;
- private boolean mHasStartedAnyProvisionalLoad = false;
+ private boolean mStartedNonApiProvisionalLoadInMainFrame = false;
- public AwWebContentsObserver(WebContents webContents, AwContentsClient awContentsClient) {
+ public AwWebContentsObserver(
+ WebContents webContents, AwContents awContents, AwContentsClient awContentsClient) {
super(webContents);
+ mAwContents = new WeakReference<AwContents>(awContents);
mAwContentsClient = awContentsClient;
}
- boolean hasStartedAnyProvisionalLoad() {
- return mHasStartedAnyProvisionalLoad;
+ boolean hasStartedNonApiProvisionalLoadInMainFrame() {
+ return mStartedNonApiProvisionalLoadInMainFrame;
}
@Override
@@ -81,6 +88,14 @@ public class AwWebContentsObserver extends WebContentsObserver {
String validatedUrl,
boolean isErrorPage,
boolean isIframeSrcdoc) {
- mHasStartedAnyProvisionalLoad = true;
+ if (!isMainFrame) return;
+ AwContents awContents = mAwContents.get();
+ if (awContents != null) {
+ NavigationEntry pendingEntry = awContents.getNavigationController().getPendingEntry();
+ if (pendingEntry != null
+ && (pendingEntry.getTransition() & PageTransition.FROM_API) == 0) {
+ mStartedNonApiProvisionalLoadInMainFrame = true;
+ }
+ }
}
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java
index fc4cc68b62..bb8e2ae7a2 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwWebContentsObserverTest.java
@@ -34,7 +34,8 @@ public class AwWebContentsObserverTest extends AwTestBase {
@Override
public void run() {
mWebContentsObserver = new AwWebContentsObserver(
- mTestContainerView.getContentViewCore().getWebContents(), mContentsClient);
+ mTestContainerView.getContentViewCore().getWebContents(),
+ mTestContainerView.getAwContents(), mContentsClient);
}
});
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java
index b657d9d54b..e9307a33c0 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/ClientOnPageFinishedTest.java
@@ -282,7 +282,7 @@ public class ClientOnPageFinishedTest extends AwTestBase {
public void testOnPageFinishedNotCalledOnDomModificationForBlankWebView() throws Throwable {
TestWebServer webServer = TestWebServer.start();
try {
- doTestOnPageFinishedNotCalledOnDomMutation(webServer);
+ doTestOnPageFinishedNotCalledOnDomMutation(webServer, null);
} finally {
webServer.shutdown();
}
@@ -290,20 +290,14 @@ public class ClientOnPageFinishedTest extends AwTestBase {
@MediumTest
@Feature({"AndroidWebView"})
- public void testOnPageFinishedCalledOnDomModificationAfterNonCommittedLoad() throws Throwable {
+ public void testOnPageFinishedNotCalledOnDomModificationAfterNonCommittedLoadFromApi()
+ throws Throwable {
enableJavaScriptOnUiThread(mAwContents);
TestWebServer webServer = TestWebServer.start();
try {
final String noContentUrl = webServer.setResponseWithNoContentStatus("/nocontent.html");
- TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
- mContentsClient.getOnPageFinishedHelper();
- final int onPageFinishedCallCount = onPageFinishedHelper.getCallCount();
loadUrlAsync(mAwContents, noContentUrl);
- // Mutate DOM.
- executeJavaScriptAndWaitForResult(mAwContents, mContentsClient,
- "document.body.innerHTML='Hello, World!'");
- onPageFinishedHelper.waitForCallback(onPageFinishedCallCount);
- assertEquals("about:blank", onPageFinishedHelper.getUrl());
+ doTestOnPageFinishedNotCalledOnDomMutation(webServer, noContentUrl);
} finally {
webServer.shutdown();
}
@@ -317,7 +311,7 @@ public class ClientOnPageFinishedTest extends AwTestBase {
final String testUrl =
webServer.setResponse("/test.html", CommonResources.ABOUT_HTML, null);
loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), testUrl);
- doTestOnPageFinishedNotCalledOnDomMutation(webServer);
+ doTestOnPageFinishedNotCalledOnDomMutation(webServer, null);
} finally {
webServer.shutdown();
}
@@ -331,13 +325,13 @@ public class ClientOnPageFinishedTest extends AwTestBase {
try {
loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(),
CommonResources.ABOUT_HTML, "text/html", false);
- doTestOnPageFinishedNotCalledOnDomMutation(webServer);
+ doTestOnPageFinishedNotCalledOnDomMutation(webServer, null);
} finally {
webServer.shutdown();
}
}
- private void doTestOnPageFinishedNotCalledOnDomMutation(TestWebServer webServer)
+ private void doTestOnPageFinishedNotCalledOnDomMutation(TestWebServer webServer, String syncUrl)
throws Throwable {
enableJavaScriptOnUiThread(mAwContents);
TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
@@ -350,8 +344,10 @@ public class ClientOnPageFinishedTest extends AwTestBase {
// we load another valid page. Since callbacks arrive sequentially if the next callback
// we get is for the synchronizationUrl we know that DOM mutation did not schedule
// a callback for the iframe.
- final String syncUrl = webServer.setResponse("/sync.html", "", null);
- loadUrlAsync(mAwContents, syncUrl);
+ if (syncUrl == null) {
+ syncUrl = webServer.setResponse("/sync.html", "", null);
+ loadUrlAsync(mAwContents, syncUrl);
+ }
onPageFinishedHelper.waitForCallback(onPageFinishedCallCount);
assertEquals(syncUrl, onPageFinishedHelper.getUrl());
assertEquals(onPageFinishedCallCount + 1, onPageFinishedHelper.getCallCount());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
index 2dd9faa5d0..ce16bf9e63 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigationPopupTest.java
@@ -50,8 +50,8 @@ public class NavigationPopupTest extends ChromeShellTestBase {
// Exists solely to expose protected methods to this test.
private static class TestNavigationEntry extends NavigationEntry {
public TestNavigationEntry(int index, String url, String virtualUrl, String originalUrl,
- String title, Bitmap favicon) {
- super(index, url, virtualUrl, originalUrl, title, favicon);
+ String title, Bitmap favicon, int transition) {
+ super(index, url, virtualUrl, originalUrl, title, favicon, transition);
}
}
@@ -62,9 +62,9 @@ public class NavigationPopupTest extends ChromeShellTestBase {
public TestNavigationController() {
mHistory = new TestNavigationHistory();
mHistory.addEntry(new TestNavigationEntry(
- 1, "about:blank", null, null, "About Blank", null));
+ 1, "about:blank", null, null, "About Blank", null, 0));
mHistory.addEntry(new TestNavigationEntry(
- 5, UrlUtils.encodeHtmlDataUri("<html>1</html>"), null, null, null, null));
+ 5, UrlUtils.encodeHtmlDataUri("<html>1</html>"), null, null, null, null, 0));
}
@Override
diff --git a/content/browser/frame_host/navigation_controller_android.cc b/content/browser/frame_host/navigation_controller_android.cc
index 52ef78ee5d..cdc7cad2f6 100644
--- a/content/browser/frame_host/navigation_controller_android.cc
+++ b/content/browser/frame_host/navigation_controller_android.cc
@@ -49,7 +49,8 @@ static base::android::ScopedJavaLocalRef<jobject> CreateJavaNavigationEntry(
j_virtual_url.obj(),
j_original_url.obj(),
j_title.obj(),
- j_bitmap.obj());
+ j_bitmap.obj(),
+ entry->GetTransitionType());
}
static void AddNavigationEntryToHistory(JNIEnv* env,
diff --git a/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java
index d039c8eac1..2b26d824a1 100644
--- a/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java
@@ -233,8 +233,8 @@ import org.chromium.content_public.browser.NavigationHistory;
@CalledByNative
private static NavigationEntry createNavigationEntry(int index, String url,
- String virtualUrl, String originalUrl, String title, Bitmap favicon) {
- return new NavigationEntry(index, url, virtualUrl, originalUrl, title, favicon);
+ String virtualUrl, String originalUrl, String title, Bitmap favicon, int transition) {
+ return new NavigationEntry(index, url, virtualUrl, originalUrl, title, favicon, transition);
}
private native boolean nativeCanGoBack(long nativeNavigationControllerAndroid);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/NavigationEntry.java b/content/public/android/java/src/org/chromium/content_public/browser/NavigationEntry.java
index b0295bf6bf..b818a93dc4 100644
--- a/content/public/android/java/src/org/chromium/content_public/browser/NavigationEntry.java
+++ b/content/public/android/java/src/org/chromium/content_public/browser/NavigationEntry.java
@@ -17,18 +17,20 @@ public class NavigationEntry {
private final String mVirtualUrl;
private final String mTitle;
private Bitmap mFavicon;
+ private int mTransition;
/**
* Default constructor.
*/
public NavigationEntry(int index, String url, String virtualUrl, String originalUrl,
- String title, Bitmap favicon) {
+ String title, Bitmap favicon, int transition) {
mIndex = index;
mUrl = url;
mVirtualUrl = virtualUrl;
mOriginalUrl = originalUrl;
mTitle = title;
mFavicon = favicon;
+ mTransition = transition;
}
/**
@@ -92,4 +94,8 @@ public class NavigationEntry {
public void updateFavicon(Bitmap favicon) {
mFavicon = favicon;
}
+
+ public int getTransition() {
+ return mTransition;
+ }
}