diff options
author | Andras Becsi <andras.becsi@digia.com> | 2014-07-25 15:53:07 +0200 |
---|---|---|
committer | Andras Becsi <andras.becsi@digia.com> | 2014-08-06 17:20:17 +0200 |
commit | ca30d0374020752d3ac367fdffef88a5c1fe4a48 (patch) | |
tree | d93bb8ca51657febaee379e86c422d91b905a68b /src/core/network_delegate_qt.cpp | |
parent | 7d90b44187cfa8f93df6a6341da41cf8192d18ad (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/network_delegate_qt.cpp')
-rw-r--r-- | src/core/network_delegate_qt.cpp | 140 |
1 files changed, 139 insertions, 1 deletions
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) + ); +} |