summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@digia.com>2014-07-25 15:53:07 +0200
committerAndras Becsi <andras.becsi@digia.com>2014-08-06 17:20:17 +0200
commitca30d0374020752d3ac367fdffef88a5c1fe4a48 (patch)
treed93bb8ca51657febaee379e86c422d91b905a68b /src/core
parent7d90b44187cfa8f93df6a6341da41cf8192d18ad (diff)
Add QQuick API for intercepting navigation requests
Add missing navigationRequested API to be able to intercept navigation requests. This is useful for ignoring requests for example in kiosk-like applications that want to restrinct navigation to a specific url or domain, or want to disable specific types of navigation requests (e.g. reloading, clicking links, form submissions). Change-Id: Ie375e635a3c3566527972d05f5d99b39489c5ca8 Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/core_gyp_generator.pro2
-rw-r--r--src/core/network_delegate_qt.cpp140
-rw-r--r--src/core/network_delegate_qt.h38
-rw-r--r--src/core/web_contents_adapter_client.h16
4 files changed, 184 insertions, 12 deletions
diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro
index 27ee33e51..5e6d08214 100644
--- a/src/core/core_gyp_generator.pro
+++ b/src/core/core_gyp_generator.pro
@@ -55,6 +55,7 @@ SOURCES = \
javascript_dialog_controller.cpp \
javascript_dialog_manager_qt.cpp \
media_capture_devices_dispatcher.cpp \
+ network_delegate_qt.cpp \
ozone_platform_eglfs.cpp \
process_main.cpp \
qrc_protocol_handler_qt.cpp \
@@ -99,6 +100,7 @@ HEADERS = \
javascript_dialog_controller.h \
javascript_dialog_manager_qt.h \
media_capture_devices_dispatcher.h \
+ network_delegate_qt.h \
ozone_platform_eglfs.h \
process_main.h \
qrc_protocol_handler_qt.h \
diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp
index 27807c499..424d0e631 100644
--- a/src/core/network_delegate_qt.cpp
+++ b/src/core/network_delegate_qt.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -40,3 +40,141 @@
****************************************************************************/
#include "network_delegate_qt.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/resource_request_details.h"
+#include "content/public/browser/resource_request_info.h"
+#include "content/public/common/page_transition_types.h"
+#include "net/base/load_flags.h"
+#include "net/url_request/url_request.h"
+#include "type_conversion.h"
+#include "web_contents_adapter_client.h"
+#include "web_contents_view_qt.h"
+
+namespace {
+
+int pageTransitionToNavigationType(content::PageTransition transition)
+{
+ int32 qualifier = content::PageTransitionGetQualifier(transition);
+
+ if (qualifier & content::PAGE_TRANSITION_FORWARD_BACK)
+ return WebContentsAdapterClient::BackForwardNavigation;
+
+ content::PageTransition stippedTransition = content::PageTransitionStripQualifier(transition);
+
+ switch (stippedTransition) {
+ case content::PAGE_TRANSITION_LINK:
+ return WebContentsAdapterClient::LinkClickedNavigation;
+ case content::PAGE_TRANSITION_TYPED:
+ return WebContentsAdapterClient::TypedNavigation;
+ case content::PAGE_TRANSITION_FORM_SUBMIT:
+ return WebContentsAdapterClient::FormSubmittedNavigation;
+ case content::PAGE_TRANSITION_RELOAD:
+ return WebContentsAdapterClient::ReloadNavigation;
+ default:
+ return WebContentsAdapterClient::OtherNavigation;
+ }
+}
+
+}
+
+int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::CompletionCallback &callback, GURL *)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ const content::ResourceRequestInfo *info = content::ResourceRequestInfo::ForRequest(request);
+ int renderProcessId;
+ int renderViewId;
+ if (!info || !info->GetRenderViewForRequest(request, &renderProcessId, &renderViewId))
+ // Abort the request if it has no associated render info / render view.
+ return net::ERR_ABORTED;
+
+ ResourceType::Type resourceType = info->GetResourceType();
+ // Only intercept MAIN_FRAME and SUB_FRAME.
+ if (!ResourceType::IsFrame(resourceType))
+ return net::OK;
+
+ // Track active requests since |callback| and |new_url| are valid
+ // only until OnURLRequestDestroyed is called for this request.
+ m_activeRequests.insert(request);
+
+ int navigationType = pageTransitionToNavigationType(info->GetPageTransition());
+
+ RequestParams params = {
+ toQt(request->url()),
+ resourceType == ResourceType::MAIN_FRAME,
+ navigationType,
+ renderProcessId,
+ renderViewId
+ };
+
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&NetworkDelegateQt::NotifyNavigationRequestedOnUIThread,
+ base::Unretained(this),
+ request,
+ params,
+ callback)
+ );
+
+ // We'll run the callback after we notified the UI thread.
+ return net::ERR_IO_PENDING;
+}
+
+void NetworkDelegateQt::OnURLRequestDestroyed(net::URLRequest* request)
+{
+ m_activeRequests.remove(request);
+}
+
+void NetworkDelegateQt::CompleteURLRequestOnIOThread(net::URLRequest *request,
+ int navigationRequestAction,
+ const net::CompletionCallback &callback)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ if (!m_activeRequests.contains(request))
+ return;
+
+ int error = net::OK;
+ switch (navigationRequestAction) {
+ case WebContentsAdapterClient::AcceptRequest:
+ error = net::OK;
+ break;
+ case WebContentsAdapterClient::IgnoreRequest:
+ error = net::OK;
+ // We can cancel the request here since we are on the IO thread.
+ request->Cancel();
+ break;
+ default:
+ error = net::ERR_FAILED;
+ Q_UNREACHABLE();
+ }
+ callback.Run(error);
+}
+
+void NetworkDelegateQt::NotifyNavigationRequestedOnUIThread(net::URLRequest *request,
+ RequestParams params,
+ const net::CompletionCallback &callback)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+
+ int navigationRequestAction = WebContentsAdapterClient::AcceptRequest;
+ content::RenderViewHost *rvh = content::RenderViewHost::FromID(params.renderProcessId, params.renderViewId);
+
+ if (rvh) {
+ content::WebContents *webContents = content::WebContents::FromRenderViewHost(rvh);
+ WebContentsAdapterClient *client = WebContentsViewQt::from(webContents->GetView())->client();
+ client->navigationRequested(params.navigationType, params.url, navigationRequestAction, params.isMainFrameRequest);
+ }
+
+ // Run the callback on the IO thread.
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&NetworkDelegateQt::CompleteURLRequestOnIOThread,
+ base::Unretained(this),
+ request,
+ navigationRequestAction,
+ callback)
+ );
+}
diff --git a/src/core/network_delegate_qt.h b/src/core/network_delegate_qt.h
index 9413addb3..d057b9915 100644
--- a/src/core/network_delegate_qt.h
+++ b/src/core/network_delegate_qt.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -42,22 +42,20 @@
#define NETWORK_DELEGATE_QT_H
#include "net/base/network_delegate.h"
+#include "net/base/net_errors.h"
-#include "qglobal.h"
+#include <QUrl>
+#include <QSet>
+#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE
class NetworkDelegateQt : public net::NetworkDelegate {
public:
NetworkDelegateQt() {}
virtual ~NetworkDelegateQt() {}
-
- private:
- // net::NetworkDelegate implementation.
- virtual int OnBeforeURLRequest(net::URLRequest* request, const net::CompletionCallback& callback, GURL* new_url) Q_DECL_OVERRIDE
- {
- return net::OK;
- }
-
+private:
+ // net::NetworkDelegate implementation
+ virtual int OnBeforeURLRequest(net::URLRequest* request, const net::CompletionCallback& callback, GURL* new_url) Q_DECL_OVERRIDE;
virtual int OnBeforeSendHeaders(net::URLRequest* request, const net::CompletionCallback& callback, net::HttpRequestHeaders* headers) Q_DECL_OVERRIDE
{
return net::OK;
@@ -72,7 +70,7 @@ public:
virtual void OnResponseStarted(net::URLRequest* request) Q_DECL_OVERRIDE { }
virtual void OnRawBytesRead(const net::URLRequest& request, int bytes_read) Q_DECL_OVERRIDE { }
virtual void OnCompleted(net::URLRequest* request, bool started) Q_DECL_OVERRIDE { }
- virtual void OnURLRequestDestroyed(net::URLRequest* request) Q_DECL_OVERRIDE { }
+ virtual void OnURLRequestDestroyed(net::URLRequest* request) Q_DECL_OVERRIDE;
virtual void OnPACScriptError(int line_number, const base::string16& error) Q_DECL_OVERRIDE { }
virtual AuthRequiredResponse OnAuthRequired(net::URLRequest* request, const net::AuthChallengeInfo& auth_info,
@@ -84,6 +82,24 @@ public:
virtual bool OnCanThrottleRequest(const net::URLRequest& request) const Q_DECL_OVERRIDE { return false; }
virtual int OnBeforeSocketStreamConnect(net::SocketStream* stream, const net::CompletionCallback& callback) Q_DECL_OVERRIDE { return net::OK; }
virtual void OnRequestWaitStateChange(const net::URLRequest& request, RequestWaitState state) Q_DECL_OVERRIDE { }
+
+ struct RequestParams {
+ QUrl url;
+ bool isMainFrameRequest;
+ int navigationType;
+ int renderProcessId;
+ int renderViewId;
+ };
+
+ void NotifyNavigationRequestedOnUIThread(net::URLRequest *request,
+ RequestParams params,
+ const net::CompletionCallback &callback);
+
+ void CompleteURLRequestOnIOThread(net::URLRequest *request,
+ int navigationRequestAction,
+ const net::CompletionCallback &callback);
+
+ QSet<net::URLRequest *> m_activeRequests;
};
#endif // NETWORK_DELEGATE_QT_H
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index f8f729f60..2dffb8fb5 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -110,6 +110,21 @@ public:
Save
};
+ enum NavigationRequestAction {
+ AcceptRequest,
+ // Make room in the valid range of the enum for extra actions exposed in Experimental.
+ IgnoreRequest = 0xFF
+ };
+
+ enum NavigationType {
+ LinkClickedNavigation,
+ TypedNavigation,
+ FormSubmittedNavigation,
+ BackForwardNavigation,
+ ReloadNavigation,
+ OtherNavigation
+ };
+
enum JavaScriptConsoleMessageLevel {
Info = 0,
Warning,
@@ -144,6 +159,7 @@ public:
virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect & initialGeometry) = 0;
virtual void close() = 0;
virtual bool contextMenuRequested(const WebEngineContextMenuData&) = 0;
+ virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) = 0;
virtual void requestFullScreen(bool) = 0;
virtual bool isFullScreen() const = 0;
virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) = 0;