summaryrefslogtreecommitdiffstats
path: root/android_webview
diff options
context:
space:
mode:
authorgsennton <gsennton@chromium.org>2015-10-05 05:03:28 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-05 12:04:34 +0000
commite5c3091df04749b232359b6ef22938006af840d5 (patch)
treea799e646553e566351c397e48ec9cf7afa097065 /android_webview
parent36d974b6b1d6166a25bd03b894bfdf646872a0b1 (diff)
downloadchromium_src-e5c3091df04749b232359b6ef22938006af840d5.zip
chromium_src-e5c3091df04749b232359b6ef22938006af840d5.tar.gz
chromium_src-e5c3091df04749b232359b6ef22938006af840d5.tar.bz2
Revert "Use resource throttle to implement shouldOverrideUrlLoading, core change"
Reverting because of crbug.com/534758, to fix that bug we will have to make a blink change adding a callback to let WebView know when a document is not longer loading. The current callback DidFinishLoad does not fire if a new load is in its provisional state, which is sometimes the case if we load a webpage containing a redirect in the form of a href assignment: window.location.href = '...'. This revert was not clean because of the transition to using NavigationThrottles over in https://codereview.chromium.org/1363483007 This reverts commit 777bb78a111aee919e07f5206267915a87639f88. TBR=palmer@chromium.org,jam@chromium.org BUG=534758 Review URL: https://codereview.chromium.org/1375993004 Cr-Commit-Position: refs/heads/master@{#352318}
Diffstat (limited to 'android_webview')
-rw-r--r--android_webview/browser/aw_content_browser_client.cc46
-rw-r--r--android_webview/browser/aw_contents_client_bridge_base.h4
-rw-r--r--android_webview/common/render_view_messages.h13
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java49
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java10
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java6
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java90
-rw-r--r--android_webview/native/aw_contents_client_bridge.cc14
-rw-r--r--android_webview/native/aw_contents_client_bridge.h3
-rw-r--r--android_webview/renderer/aw_content_renderer_client.cc57
-rw-r--r--android_webview/renderer/aw_content_renderer_client.h8
11 files changed, 171 insertions, 129 deletions
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index ab14d49..0c027e1 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -28,6 +28,7 @@
#include "components/navigation_interception/intercept_navigation_delegate.h"
#include "content/public/browser/access_token_store.h"
#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/navigation_handle.h"
@@ -46,6 +47,7 @@
#include "ui/base/resource/resource_bundle_android.h"
#include "ui/resources/grit/ui_resources.h"
+using content::BrowserThread;
using content::ResourceType;
namespace android_webview {
@@ -59,8 +61,15 @@ public:
explicit AwContentsMessageFilter(int process_id);
// BrowserMessageFilter methods.
+ void OverrideThreadForMessage(const IPC::Message& message,
+ BrowserThread::ID* thread) override;
bool OnMessageReceived(const IPC::Message& message) override;
+ void OnShouldOverrideUrlLoading(int routing_id,
+ const base::string16& url,
+ bool has_user_gesture,
+ bool is_redirect,
+ bool* ignore_navigation);
void OnSubFrameCreated(int parent_render_frame_id, int child_render_frame_id);
private:
@@ -79,15 +88,44 @@ AwContentsMessageFilter::AwContentsMessageFilter(int process_id)
AwContentsMessageFilter::~AwContentsMessageFilter() {
}
+void AwContentsMessageFilter::OverrideThreadForMessage(
+ const IPC::Message& message,
+ BrowserThread::ID* thread) {
+ if (message.type() == AwViewHostMsg_ShouldOverrideUrlLoading::ID) {
+ *thread = BrowserThread::UI;
+ }
+}
+
bool AwContentsMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(AwContentsMessageFilter, message)
+ IPC_MESSAGE_HANDLER(AwViewHostMsg_ShouldOverrideUrlLoading,
+ OnShouldOverrideUrlLoading)
IPC_MESSAGE_HANDLER(AwViewHostMsg_SubFrameCreated, OnSubFrameCreated)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
+void AwContentsMessageFilter::OnShouldOverrideUrlLoading(
+ int render_frame_id,
+ const base::string16& url,
+ bool has_user_gesture,
+ bool is_redirect,
+ bool* ignore_navigation) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ *ignore_navigation = false;
+ AwContentsClientBridgeBase* client =
+ AwContentsClientBridgeBase::FromID(process_id_, render_frame_id);
+ if (client) {
+ *ignore_navigation =
+ client->ShouldOverrideUrlLoading(url, has_user_gesture, is_redirect);
+ } else {
+ LOG(WARNING) << "Failed to find the associated render view host for url: "
+ << url;
+ }
+}
+
void AwContentsMessageFilter::OnSubFrameCreated(int parent_render_frame_id,
int child_render_frame_id) {
AwContentsIoThreadClient::SubFrameCreated(
@@ -494,10 +532,10 @@ ScopedVector<content::NavigationThrottle>
AwContentBrowserClient::CreateThrottlesForNavigation(
content::NavigationHandle* navigation_handle) {
ScopedVector<content::NavigationThrottle> throttles;
- if (navigation_handle->IsInMainFrame() ||
- (!navigation_handle->GetURL().SchemeIs(url::kHttpScheme) &&
- !navigation_handle->GetURL().SchemeIs(url::kHttpsScheme) &&
- !navigation_handle->GetURL().SchemeIs(url::kAboutScheme))) {
+ // We allow intercepting only navigations within main frames. This
+ // is used to post onPageStarted. We handle shouldOverrideUrlLoading
+ // via a sync IPC.
+ if (navigation_handle->IsInMainFrame()) {
throttles.push_back(
navigation_interception::InterceptNavigationDelegate::CreateThrottleFor(
navigation_handle)
diff --git a/android_webview/browser/aw_contents_client_bridge_base.h b/android_webview/browser/aw_contents_client_bridge_base.h
index 9cd9206..31c965f 100644
--- a/android_webview/browser/aw_contents_client_bridge_base.h
+++ b/android_webview/browser/aw_contents_client_bridge_base.h
@@ -62,6 +62,10 @@ class AwContentsClientBridgeBase {
const base::string16& message_text,
const content::JavaScriptDialogManager::DialogClosedCallback& callback)
= 0;
+
+ virtual bool ShouldOverrideUrlLoading(const base::string16& url,
+ bool has_user_gesture,
+ bool is_redirect) = 0;
};
} // namespace android_webview
diff --git a/android_webview/common/render_view_messages.h b/android_webview/common/render_view_messages.h
index 91dbb5b..bdd6711 100644
--- a/android_webview/common/render_view_messages.h
+++ b/android_webview/common/render_view_messages.h
@@ -104,6 +104,19 @@ IPC_MESSAGE_ROUTED1(AwViewHostMsg_PageScaleFactorChanged,
IPC_MESSAGE_ROUTED1(AwViewHostMsg_OnContentsSizeChanged,
gfx::Size /* contents_size */)
+// Sent immediately before a top level navigation is initiated within Blink.
+// There are some exlusions, the most important ones are it is not sent
+// when creating a popup window, and not sent for application initiated
+// navigations. See AwContentRendererClient::HandleNavigation for all
+// cornercases. This is sent before updating the NavigationController state
+// or creating a URLRequest for the main frame resource.
+IPC_SYNC_MESSAGE_CONTROL4_1(AwViewHostMsg_ShouldOverrideUrlLoading,
+ int /* render_frame_id id */,
+ base::string16 /* in - url */,
+ bool /* in - has_user_gesture */,
+ bool /* in - is_redirect */,
+ bool /* out - result */)
+
// Sent when a subframe is created.
IPC_MESSAGE_CONTROL2(AwViewHostMsg_SubFrameCreated,
int /* parent_render_frame_id */,
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 89eff61..7962c18 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -279,6 +279,10 @@ public class AwContents implements SmartClipProvider,
private PostMessageSender mPostMessageSender;
+ // This flag indicates that ShouldOverrideUrlNavigation should be posted
+ // through the resourcethrottle. This is only used for popup windows.
+ private boolean mDeferredShouldOverrideUrlLoadingIsPendingForPopup;
+
// This is a workaround for some qualcomm devices discarding buffer on
// Activity restore.
private boolean mInvalidateRootViewOnNextDraw;
@@ -488,42 +492,26 @@ public class AwContents implements SmartClipProvider,
@Override
public boolean shouldIgnoreNavigation(NavigationParams navigationParams) {
final String url = navigationParams.url;
-
- final int transitionType = navigationParams.pageTransitionType;
- final boolean isLoadUrl = (transitionType & PageTransition.FROM_API) != 0;
- final boolean isBackForward = (transitionType & PageTransition.FORWARD_BACK) != 0;
- final boolean isReload =
- (transitionType & PageTransition.CORE_MASK) == PageTransition.RELOAD;
- final boolean isRedirect = navigationParams.isRedirect;
-
boolean ignoreNavigation = false;
- // Any navigation from loadUrl, goBack/Forward, or reload, are considered application
- // initiated and hence will not yield a shouldOverrideUrlLoading() callback.
- if ((!isLoadUrl || isRedirect) && !isBackForward && !isReload
- && !navigationParams.isPost) {
- if (!mContentsClient.hasWebViewClient()) {
- ignoreNavigation = AwContentsClient.sendBrowsingIntent(mContext, url,
- navigationParams.hasUserGesture
- || navigationParams.hasUserGestureCarryover,
- navigationParams.isRedirect);
- } else {
- ignoreNavigation = mContentsClient.shouldOverrideUrlLoading(url);
+ if (mDeferredShouldOverrideUrlLoadingIsPendingForPopup) {
+ mDeferredShouldOverrideUrlLoadingIsPendingForPopup = false;
+ // If this is used for all navigations in future, cases for application initiated
+ // load, redirect and backforward should also be filtered out.
+ if (!navigationParams.isPost) {
+ if (!mContentsClient.hasWebViewClient()) {
+ ignoreNavigation = AwContentsClient.sendBrowsingIntent(mContext, url,
+ navigationParams.hasUserGesture
+ || navigationParams.hasUserGestureCarryover,
+ navigationParams.isRedirect);
+ } else {
+ ignoreNavigation = mContentsClient.shouldOverrideUrlLoading(url);
+ }
}
}
-
// The shouldOverrideUrlLoading call might have resulted in posting messages to the
// UI thread. Using sendMessage here (instead of calling onPageStarted directly)
// will allow those to run in order.
- if (isRedirect) {
- mContentsClient.getCallbackHelper().postOnPageStarted(url);
- // We can post onPageFinished here since we know that the navigation will fail.
- // Also AwWebContentsObserver.didFail does not call OnPageFinished when the
- // navigation is overridden because we don't want an onPageFinished for such a
- // navigation unless it is a redirect.
- if (ignoreNavigation) {
- mContentsClient.getCallbackHelper().postOnPageFinished(url);
- }
- } else if (!ignoreNavigation) {
+ if (!ignoreNavigation) {
mContentsClient.getCallbackHelper().postOnPageStarted(url);
}
return ignoreNavigation;
@@ -1010,6 +998,7 @@ public class AwContents implements SmartClipProvider,
// Recap: supplyContentsForPopup() is called on the parent window's content, this method is
// called on the popup window's content.
private void receivePopupContents(long popupNativeAwContents) {
+ mDeferredShouldOverrideUrlLoadingIsPendingForPopup = true;
// Save existing view state.
final boolean wasAttached = mIsAttachedToWindow;
final boolean wasViewVisible = mIsViewVisible;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
index c1b03a1..76cb761 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClientBridge.java
@@ -259,6 +259,16 @@ public class AwContentsClientBridge {
mClient.handleJsBeforeUnload(url, message, handler);
}
+ @CalledByNative
+ private boolean shouldOverrideUrlLoading(
+ String url, boolean hasUserGesture, boolean isRedirect) {
+ if (mClient.hasWebViewClient()) {
+ return mClient.shouldOverrideUrlLoading(url);
+ } else {
+ return AwContentsClient.sendBrowsingIntent(mContext, url, hasUserGesture, isRedirect);
+ }
+ }
+
void confirmJsResult(int id, String prompt) {
if (mNativeContentsClientBridge == 0) return;
nativeConfirmJsResult(mNativeContentsClientBridge, id, prompt);
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 53715c6..85cf90c 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
@@ -53,13 +53,9 @@ public class AwWebContentsObserver extends WebContentsObserver {
String unreachableWebDataUrl = AwContentsStatics.getUnreachableWebDataUrl();
boolean isErrorUrl =
unreachableWebDataUrl != null && unreachableWebDataUrl.equals(failingUrl);
- if (isMainFrame && !isErrorUrl && errorCode == NetError.ERR_ABORTED
- && !wasIgnoredByHandler) {
+ if (isMainFrame && !isErrorUrl && errorCode == NetError.ERR_ABORTED) {
// Need to call onPageFinished for backwards compatibility with the classic webview.
// See also AwContents.IoThreadClientImpl.onReceivedError.
- // If the navigation was ignored because of shouldOverrideUrlLoading we have already
- // called onPageFinished in
- // AwContents.InterceptNavigationDelegateImpl.shouldIgnoreNavigation instead.
client.getCallbackHelper().postOnPageFinished(failingUrl);
}
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
index 86d082d..6aadfd8 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
@@ -11,7 +11,6 @@ import android.util.Pair;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.JSUtils;
-import org.chromium.android_webview.test.util.JavascriptEventObserver;
import org.chromium.base.annotations.SuppressFBWarnings;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
@@ -27,7 +26,6 @@ import org.chromium.net.test.util.TestWebServer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
@@ -1040,92 +1038,4 @@ public class AwContentsClientShouldOverrideUrlLoadingTest extends AwTestBase {
getActivity().setIgnoreStartActivity(false);
}
}
-
- @SmallTest
- @Feature({"AndroidWebView"})
- public void testXhrInLink() throws Throwable {
- final TestAwContentsClient contentsClient = new TestAwContentsClient();
- final AwTestContainerView testContainerView =
- createAwTestContainerViewOnMainSync(contentsClient);
- final AwContents awContents = testContainerView.getAwContents();
- TestAwContentsClient.ShouldOverrideUrlLoadingHelper shouldOverrideUrlLoadingHelper =
- contentsClient.getShouldOverrideUrlLoadingHelper();
-
- final CountDownLatch shouldOverrideUrlLoadingSignal = new CountDownLatch(1);
-
- final String xhrPath = "/xhrPath.html";
- final String xhrUrl = mWebServer.setResponseWithRunnableAction(
- xhrPath, CommonResources.makeHtmlPageFrom("", ""), null, new Runnable() {
- @Override
- public void run() {
- try {
- shouldOverrideUrlLoadingSignal.await();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- });
-
- final String xhrJs = "function xhrFunction() {"
- + " var xhr = new XMLHttpRequest();"
- + " xhr.onload=function() {"
- + " console.info('xhr loaded');"
- + " window.jsInterface.setValue(true);"
- + " };"
- + " xhr.onerror=function() {"
- + " console.info('xhr failed, status ' + xhr.status);"
- + " window.jsInterface.setValue(false);"
- + " };"
- + " xhr.open('GET', '" + xhrUrl + "', true);"
- + " xhr.send();"
- + "};";
-
- String pageWithXhrLink = makeHtmlPageFrom(
- "<script>" + xhrJs + "</script>",
- "<img onclick=\"xhrFunction(); location.href='"
- + "thiswillbe://intercepted/"
- + "'\" class=\"big\" id=\"link\" />");
-
- final String startPath = "/startPath.html";
- final String startUrl = addPageToTestServer(mWebServer, startPath, pageWithXhrLink);
-
- enableJavaScriptOnUiThread(awContents);
- final BooleanValueJavascriptObserver jsInterface = new BooleanValueJavascriptObserver();
-
- // add javascript interface
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- jsInterface.register(awContents.getContentViewCore(), "jsInterface");
- }
- });
-
- loadUrlSync(awContents, contentsClient.getOnPageFinishedHelper(), startUrl);
-
- setShouldOverrideUrlLoadingReturnValueOnUiThread(shouldOverrideUrlLoadingHelper, true);
- final int shouldOverrideUrlLoadingCallCount = shouldOverrideUrlLoadingHelper.getCallCount();
-
- clickOnLinkUsingJs(awContents, contentsClient);
-
- // Make the server xhr response wait until the navigation request is intercepted.
- shouldOverrideUrlLoadingHelper.waitForCallback(shouldOverrideUrlLoadingCallCount);
- shouldOverrideUrlLoadingSignal.countDown();
-
- jsInterface.waitForEvent(WAIT_TIMEOUT_MS);
- assertTrue(jsInterface.getValue());
- assertEquals(1, mWebServer.getRequestCount(xhrPath));
- }
-
- private static class BooleanValueJavascriptObserver extends JavascriptEventObserver {
- private boolean mValue = false;
-
- public void setValue(boolean value) {
- mValue = value;
- notifyJava();
- }
-
- public boolean getValue() {
- return mValue;
- }
- }
}
diff --git a/android_webview/native/aw_contents_client_bridge.cc b/android_webview/native/aw_contents_client_bridge.cc
index 9e570af..6890955 100644
--- a/android_webview/native/aw_contents_client_bridge.cc
+++ b/android_webview/native/aw_contents_client_bridge.cc
@@ -340,6 +340,20 @@ void AwContentsClientBridge::RunBeforeUnloadDialog(
env, obj.obj(), jurl.obj(), jmessage.obj(), callback_id);
}
+bool AwContentsClientBridge::ShouldOverrideUrlLoading(const base::string16& url,
+ bool has_user_gesture,
+ bool is_redirect) {
+ 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");
+ return Java_AwContentsClientBridge_shouldOverrideUrlLoading(
+ env, obj.obj(), jurl.obj(), has_user_gesture, is_redirect);
+}
+
void AwContentsClientBridge::ConfirmJsResult(JNIEnv* env,
jobject,
int id,
diff --git a/android_webview/native/aw_contents_client_bridge.h b/android_webview/native/aw_contents_client_bridge.h
index 74f13e0..0595ba0 100644
--- a/android_webview/native/aw_contents_client_bridge.h
+++ b/android_webview/native/aw_contents_client_bridge.h
@@ -54,6 +54,9 @@ class AwContentsClientBridge : public AwContentsClientBridgeBase {
const base::string16& message_text,
const content::JavaScriptDialogManager::DialogClosedCallback& callback)
override;
+ bool ShouldOverrideUrlLoading(const base::string16& url,
+ bool has_user_gesture,
+ bool is_redirect) override;
// Methods called from Java.
void ProceedSslError(JNIEnv* env, jobject obj, jboolean proceed, jint id);
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc
index 34f4b75..db1eb0a 100644
--- a/android_webview/renderer/aw_content_renderer_client.cc
+++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -29,6 +29,8 @@
#include "components/printing/renderer/print_web_view_helper.h"
#include "components/visitedlink/renderer/visitedlink_slave.h"
#include "content/public/common/url_constants.h"
+#include "content/public/renderer/document_state.h"
+#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
@@ -39,6 +41,7 @@
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebNavigationType.h"
#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
@@ -76,6 +79,60 @@ void AwContentRendererClient::RenderThreadStarted() {
blink::WebSecurityPolicy::registerURLSchemeAsSecure(aw_scheme);
}
+bool AwContentRendererClient::HandleNavigation(
+ content::RenderFrame* render_frame,
+ content::DocumentState* document_state,
+ int opener_id,
+ blink::WebFrame* frame,
+ const blink::WebURLRequest& request,
+ blink::WebNavigationType type,
+ blink::WebNavigationPolicy default_policy,
+ bool is_redirect) {
+ // Only GETs can be overridden.
+ if (!request.httpMethod().equals("GET"))
+ return false;
+
+ // Any navigation from loadUrl, and goBack/Forward are considered application-
+ // initiated and hence will not yield a shouldOverrideUrlLoading() callback.
+ // Webview classic does not consider reload application-initiated so we
+ // continue the same behavior.
+ // TODO(sgurun) is_content_initiated is normally false for cross-origin
+ // navigations but since android_webview does not swap out renderers, this
+ // works fine. This will stop working if android_webview starts swapping out
+ // renderers on navigation.
+ bool application_initiated =
+ !document_state->navigation_state()->IsContentInitiated() ||
+ type == blink::WebNavigationTypeBackForward;
+
+ // Don't offer application-initiated navigations unless it's a redirect.
+ if (application_initiated && !is_redirect)
+ return false;
+
+ const GURL& gurl = request.url();
+ // For HTTP schemes, only top-level navigations can be overridden. Similarly,
+ // WebView Classic lets app override only top level about:blank navigations.
+ // So we filter out non-top about:blank navigations here.
+ if (frame->parent() &&
+ (gurl.SchemeIs(url::kHttpScheme) || gurl.SchemeIs(url::kHttpsScheme) ||
+ gurl.SchemeIs(url::kAboutScheme)))
+ return false;
+
+ // use NavigationInterception throttle to handle the call as that can
+ // be deferred until after the java side has been constructed.
+ if (opener_id != MSG_ROUTING_NONE) {
+ return false;
+ }
+
+ bool ignore_navigation = false;
+ base::string16 url = request.url().string();
+ bool has_user_gesture = request.hasUserGesture();
+
+ int render_frame_id = render_frame->GetRoutingID();
+ RenderThread::Get()->Send(new AwViewHostMsg_ShouldOverrideUrlLoading(
+ render_frame_id, url, has_user_gesture, is_redirect, &ignore_navigation));
+ return ignore_navigation;
+}
+
void AwContentRendererClient::RenderFrameCreated(
content::RenderFrame* render_frame) {
new AwContentSettingsClient(render_frame);
diff --git a/android_webview/renderer/aw_content_renderer_client.h b/android_webview/renderer/aw_content_renderer_client.h
index f58da53..8d05aab 100644
--- a/android_webview/renderer/aw_content_renderer_client.h
+++ b/android_webview/renderer/aw_content_renderer_client.h
@@ -37,6 +37,14 @@ class AwContentRendererClient : public content::ContentRendererClient {
bool IsLinkVisited(unsigned long long link_hash) override;
void AddKeySystems(std::vector<media::KeySystemInfo>* key_systems) override;
+ bool HandleNavigation(content::RenderFrame* render_frame,
+ content::DocumentState* document_state,
+ int opener_id,
+ blink::WebFrame* frame,
+ const blink::WebURLRequest& request,
+ blink::WebNavigationType type,
+ blink::WebNavigationPolicy default_policy,
+ bool is_redirect) override;
bool ShouldOverridePageVisibilityState(
const content::RenderFrame* render_frame,
blink::WebPageVisibilityState* override_state) override;