From a029fa2f6ef08bcad653f3d3e5a53ca8e3340b14 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Thu, 18 Sep 2014 18:21:28 +0200 Subject: Wire the geolocation API to QtPositioning If QtPositioning is available, provide chromium with a LocationProvider that uses it as a backend. Change-Id: I53ad3b45e49d0d2d181c1a6459b7be764293c2a6 Reviewed-by: Andras Becsi --- src/3rdparty | 2 +- src/core/access_token_store_qt.cpp | 50 ++++++ src/core/access_token_store_qt.h | 38 +++++ src/core/content_browser_client_qt.cpp | 38 +++-- src/core/content_browser_client_qt.h | 12 +- src/core/core_gyp_generator.pro | 9 + src/core/core_module.pro | 1 + src/core/location_provider_qt.cpp | 248 ++++++++++++++++++++++++++++ src/core/location_provider_qt.h | 76 +++++++++ src/core/type_conversion.h | 4 + src/core/web_contents_adapter.cpp | 6 + src/core/web_contents_adapter.h | 1 + src/core/web_contents_adapter_client.h | 1 + src/core/web_contents_delegate_qt.cpp | 6 + src/core/web_contents_delegate_qt.h | 4 + src/webengine/api/qquickwebengineview_p_p.h | 1 + src/webenginewidgets/api/qwebenginepage.cpp | 12 ++ src/webenginewidgets/api/qwebenginepage_p.h | 1 + 18 files changed, 488 insertions(+), 22 deletions(-) create mode 100644 src/core/access_token_store_qt.cpp create mode 100644 src/core/access_token_store_qt.h create mode 100644 src/core/location_provider_qt.cpp create mode 100644 src/core/location_provider_qt.h (limited to 'src') diff --git a/src/3rdparty b/src/3rdparty index 0dcd4e350..66388297c 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit 0dcd4e35086a90f643bb721fad1ef786f5fff8ba +Subproject commit 66388297cf2ca42049fb099237134ec33465e2f5 diff --git a/src/core/access_token_store_qt.cpp b/src/core/access_token_store_qt.cpp new file mode 100644 index 000000000..b007d372f --- /dev/null +++ b/src/core/access_token_store_qt.cpp @@ -0,0 +1,50 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "access_token_store_qt.h" + +#include "base/bind.h" +#include "base/message_loop/message_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/browser_thread.h" + +#include "browser_context_qt.h" +#include "browser_context_adapter.h" +#include "content_browser_client_qt.h" +#include "web_engine_context.h" + +using content::AccessTokenStore; +using content::BrowserThread; + +AccessTokenStoreQt::AccessTokenStoreQt() + : m_systemRequestContext(0) +{ +} + +AccessTokenStoreQt::~AccessTokenStoreQt() +{ +} + +void AccessTokenStoreQt::LoadAccessTokens(const LoadAccessTokensCallbackType& callback) +{ + BrowserThread::PostTaskAndReply(BrowserThread::UI, FROM_HERE + , base::Bind(&AccessTokenStoreQt::performWorkOnUIThread, this) + , base::Bind(&AccessTokenStoreQt::respondOnOriginatingThread, this, callback)); +} + +void AccessTokenStoreQt::performWorkOnUIThread() +{ + m_systemRequestContext = WebEngineContext::current()->defaultBrowserContext()->browserContext()->GetRequestContext(); +} + +void AccessTokenStoreQt::respondOnOriginatingThread(const LoadAccessTokensCallbackType& callback) +{ + callback.Run(m_accessTokenSet, m_systemRequestContext); + m_systemRequestContext = 0; +} + +void AccessTokenStoreQt::SaveAccessToken(const GURL& serverUrl, const base::string16& accessToken) +{ + m_accessTokenSet[serverUrl] = accessToken; +} diff --git a/src/core/access_token_store_qt.h b/src/core/access_token_store_qt.h new file mode 100644 index 000000000..4fbbde5f0 --- /dev/null +++ b/src/core/access_token_store_qt.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ACCESS_TOKEN_STORE_QT_H +#define ACCESS_TOKEN_STORE_QT_H + +#include "base/memory/ref_counted.h" +#include "content/public/browser/access_token_store.h" + +#include +#include +#include + +namespace net { +class URLRequestContextGetter; +} + +class AccessTokenStoreQt : public content::AccessTokenStore { +public: + AccessTokenStoreQt(); + + virtual void LoadAccessTokens(const LoadAccessTokensCallbackType& request) Q_DECL_OVERRIDE; + virtual void SaveAccessToken(const GURL& serverUrl, const base::string16& accessToken) Q_DECL_OVERRIDE; + +private: + virtual ~AccessTokenStoreQt(); + void performWorkOnUIThread(); + void respondOnOriginatingThread(const LoadAccessTokensCallbackType& callback); + + + net::URLRequestContextGetter *m_systemRequestContext; + AccessTokenSet m_accessTokenSet; + + DISALLOW_COPY_AND_ASSIGN(AccessTokenStoreQt); +}; + +#endif // ACCESS_TOKEN_STORE_QT_H diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index 2aca88d6a..2ebd3cfad 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -54,11 +54,15 @@ #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_share_group.h" +#include "access_token_store_qt.h" #include "browser_context_qt.h" #include "certificate_error_controller.h" #include "certificate_error_controller_p.h" #include "desktop_screen_qt.h" #include "dev_tools_http_handler_delegate_qt.h" +#ifdef QT_USE_POSITIONING +#include "location_provider_qt.h" +#endif #include "media_capture_devices_dispatcher.h" #include "resource_dispatcher_host_delegate_qt.h" #include "web_contents_delegate_qt.h" @@ -332,6 +336,13 @@ content::MediaObserver *ContentBrowserClientQt::GetMediaObserver() return MediaCaptureDevicesDispatcher::GetInstance(); } +content::AccessTokenStore *ContentBrowserClientQt::CreateAccessTokenStore() +{ + // We return a dumb in-memory AccessTokenStore implementation for now + // since this is not null-checked before it's used in the content layer. + return new AccessTokenStoreQt; +} + void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, const GURL &url, WebPreferences *web_prefs) { Q_UNUSED(url); @@ -372,19 +383,18 @@ void ContentBrowserClientQt::AllowCertificateError(int render_process_id, int re contentsDelegate->allowCertificateError(errorController); } -void ContentBrowserClientQt::RequestGeolocationPermission(content::WebContents *webContents, - int bridge_id, - const GURL &requesting_frame, - bool user_gesture, - base::Callback result_callback, - base::Closure *cancel_callback) +void ContentBrowserClientQt::RequestGeolocationPermission(content::WebContents *webContents, int /*bridgeId*/, const GURL &requestingFrameOrigin, bool /*userGesture*/, base::Callback resultCallback, base::Closure *cancelCallback) +{ + WebContentsDelegateQt* contentsDelegate = static_cast(webContents->GetDelegate()); + Q_ASSERT(contentsDelegate); + contentsDelegate->requestGeolocationPermission(requestingFrameOrigin, resultCallback, cancelCallback); +} + +content::LocationProvider *ContentBrowserClientQt::OverrideSystemLocationProvider() { - Q_UNUSED(webContents); - Q_UNUSED(bridge_id); - Q_UNUSED(requesting_frame); - Q_UNUSED(user_gesture); - Q_UNUSED(cancel_callback); - - // TODO: Add geolocation support - result_callback.Run(false); +#ifdef QT_USE_POSITIONING + return new LocationProviderQt; +#else + return 0; // Leave it up to Chromium to figure something out. +#endif } diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index ed328d1bf..985624cd9 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -78,6 +78,7 @@ public: virtual void ResourceDispatcherHostCreated() Q_DECL_OVERRIDE; virtual gfx::GLShareGroup* GetInProcessGpuShareGroup() Q_DECL_OVERRIDE; virtual content::MediaObserver* GetMediaObserver() Q_DECL_OVERRIDE; + virtual content::AccessTokenStore* CreateAccessTokenStore() Q_DECL_OVERRIDE; virtual void OverrideWebkitPrefs(content::RenderViewHost *, const GURL &, WebPreferences *) Q_DECL_OVERRIDE; virtual void AllowCertificateError( int render_process_id, @@ -90,13 +91,10 @@ public: bool strict_enforcement, const base::Callback& callback, content::CertificateRequestResultType* result) Q_DECL_OVERRIDE; - virtual void RequestGeolocationPermission( - content::WebContents *webContents, - int bridge_id, - const GURL &requesting_frame, - bool user_gesture, - base::Callback result_callback, - base::Closure *cancel_callback) Q_DECL_OVERRIDE; + void RequestGeolocationPermission(content::WebContents* web_contents, int, const GURL& requesting_frame + , bool, base::Callback resultCallback + , base::Closure* cancelCallback) Q_DECL_OVERRIDE; + content::LocationProvider* OverrideSystemLocationProvider() Q_DECL_OVERRIDE; virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *content_browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE; diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro index 15eee1f09..a011effec 100644 --- a/src/core/core_gyp_generator.pro +++ b/src/core/core_gyp_generator.pro @@ -33,6 +33,7 @@ RESOURCES += devtools.qrc INCLUDEPATH += $$[QT_INSTALL_HEADERS] $$PWD SOURCES = \ + access_token_store_qt.cpp \ browser_accessibility_manager_qt.cpp \ browser_accessibility_qt.cpp \ browser_context_adapter.cpp \ @@ -81,6 +82,7 @@ SOURCES = \ yuv_video_node.cpp HEADERS = \ + access_token_store_qt.h \ browser_accessibility_manager_qt.h \ browser_accessibility_qt.h \ browser_context_adapter.h \ @@ -132,3 +134,10 @@ HEADERS = \ web_engine_visited_links_manager.h \ web_event_factory.h \ yuv_video_node.h + +qtHaveModule(positioning) { + SOURCES += location_provider_qt.cpp + HEADERS += location_provider_qt.h + DEFINES += QT_USE_POSITIONING=1 + QT += positioning +} diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 08e0b7822..c755d673d 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -3,6 +3,7 @@ TARGET = QtWebEngineCore CMAKE_MODULE_TESTS = "-" +qtHaveModule(positioning):QT += positioning QT += qml quick QT_PRIVATE += gui-private diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp new file mode 100644 index 000000000..cdc9f1a44 --- /dev/null +++ b/src/core/location_provider_qt.cpp @@ -0,0 +1,248 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "location_provider_qt.h" + +#include + +#include "type_conversion.h" + +#include +#include +#include + +#include "base/message_loop/message_loop.h" +#include "base/bind.h" +#include "content/browser/geolocation/geolocation_provider_impl.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/geolocation_provider.h" + +using content::BrowserThread; + +class QtPositioningHelper : public QObject { + Q_OBJECT +public: + QtPositioningHelper(LocationProviderQt *provider); + ~QtPositioningHelper(); + + bool start(bool highAccuracy); + void stop(); + void refresh(); + +private Q_SLOTS: + void updatePosition(const QGeoPositionInfo &); + void error(QGeoPositionInfoSource::Error positioningError); + void timeout(); + +private: + LocationProviderQt *m_locationProvider; + QGeoPositionInfoSource *m_positionInfoSource; + + void postToLocationProvider(const base::Closure &task); +}; + +QtPositioningHelper::QtPositioningHelper(LocationProviderQt *provider) + : m_locationProvider(provider) + , m_positionInfoSource(0) +{ + Q_ASSERT(provider); +} + +QtPositioningHelper::~QtPositioningHelper() +{ + m_locationProvider->m_positioningHelper = 0; +} + +bool QtPositioningHelper::start(bool highAccuracy) +{ + DCHECK_CURRENTLY_ON(BrowserThread::UI); + Q_UNUSED(highAccuracy); + // FIXME: go through availableSources until one supports QGeoPositionInfoSource::SatellitePositioningMethods + // for the highAccuracy case. + m_positionInfoSource = QGeoPositionInfoSource::createDefaultSource(this); + if (!m_positionInfoSource) + return false; + + connect(m_positionInfoSource, &QGeoPositionInfoSource::positionUpdated, this, &QtPositioningHelper::updatePosition); + // disambiguate the error getter and the signal in QGeoPositionInfoSource. + connect(m_positionInfoSource, static_cast(&QGeoPositionInfoSource::error) + , this, &QtPositioningHelper::error); + connect(m_positionInfoSource, &QGeoPositionInfoSource::updateTimeout, this, &QtPositioningHelper::timeout); + + m_positionInfoSource->startUpdates(); + return true; +} + +void QtPositioningHelper::stop() +{ + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!m_positionInfoSource) + return; + m_positionInfoSource->stopUpdates(); +} + +void QtPositioningHelper::refresh() +{ + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!m_positionInfoSource) + return; + m_positionInfoSource->stopUpdates(); +} + +void QtPositioningHelper::updatePosition(const QGeoPositionInfo &pos) +{ + if (!pos.isValid()) + return; + Q_ASSERT(m_positionInfoSource->error() == QGeoPositionInfoSource::NoError); + content::Geoposition newPos; + newPos.error_code = content::Geoposition::ERROR_CODE_NONE; + newPos.error_message.clear(); + + newPos.timestamp = toTime(pos.timestamp()); + newPos.latitude = pos.coordinate().latitude(); + newPos.longitude = pos.coordinate().longitude(); + + const double altitude = pos.coordinate().altitude(); + if (!qIsNaN(altitude)) + newPos.altitude = altitude; + + // Chromium's geoposition needs a valid (as in >=0.) accuracy field. + // try and get an accuracy estimate from QGeoPositionInfo. + // If we don't have any accuracy info, 100m seems a pesimistic enough default. + if (!pos.hasAttribute(QGeoPositionInfo::VerticalAccuracy) && !pos.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) + newPos.accuracy = 100; + else { + const double vAccuracy = pos.hasAttribute(QGeoPositionInfo::VerticalAccuracy) ? pos.attribute(QGeoPositionInfo::VerticalAccuracy) : 0; + const double hAccuracy = pos.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) ? pos.attribute(QGeoPositionInfo::HorizontalAccuracy) : 0; + newPos.accuracy = sqrt(vAccuracy * vAccuracy + hAccuracy * hAccuracy); + } + + // And now the "nice to have" fields (-1 means invalid). + newPos.speed = pos.hasAttribute(QGeoPositionInfo::GroundSpeed) ? pos.attribute(QGeoPositionInfo::GroundSpeed) : -1; + newPos.heading = pos.hasAttribute(QGeoPositionInfo::Direction) ? pos.attribute(QGeoPositionInfo::Direction) : -1; + + postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos)); +} + +void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError) +{ + Q_ASSERT(positioningError != QGeoPositionInfoSource::NoError); + content::Geoposition newPos; + switch (positioningError) { + case QGeoPositionInfoSource::AccessError: + newPos.error_code = content::Geoposition::ERROR_CODE_PERMISSION_DENIED; + break; + case QGeoPositionInfoSource::ClosedError: + case QGeoPositionInfoSource::UnknownSourceError: // position unavailable is as good as it gets in Geoposition + default: + newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; + break; + } + postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos)); +} + +void QtPositioningHelper::timeout() +{ + content::Geoposition newPos; + // content::Geoposition::ERROR_CODE_TIMEOUT is not handled properly in the renderer process, and the timeout + // argument used in JS never comes all the way to the browser process. + // Let's just treat it like any other error where the position is unavailable. + newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; + postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos)); +} + +inline void QtPositioningHelper::postToLocationProvider(const base::Closure &task) +{ + LocationProviderQt::messageLoop()->PostTask(FROM_HERE, task); +} + +#include "location_provider_qt.moc" + +LocationProviderQt::LocationProviderQt() + : m_positioningHelper(0) +{ +} + +LocationProviderQt::~LocationProviderQt() +{ + m_positioningHelper->deleteLater(); +} + +bool LocationProviderQt::StartProvider(bool highAccuracy) +{ + DCHECK(base::MessageLoop::current() == messageLoop()); + QThread *guiThread = qApp->thread(); + if (!m_positioningHelper) { + m_positioningHelper = new QtPositioningHelper(this); + m_positioningHelper->moveToThread(guiThread); + } + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(base::IgnoreResult(&QtPositioningHelper::start) + , base::Unretained(m_positioningHelper), highAccuracy)); + return true; +} + +void LocationProviderQt::StopProvider() +{ + DCHECK(base::MessageLoop::current() == messageLoop()); + if (m_positioningHelper) + BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::stop + , base::Unretained(m_positioningHelper))); +} + +void LocationProviderQt::RequestRefresh() +{ + DCHECK(base::MessageLoop::current() == messageLoop()); + if (m_positioningHelper) + BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::refresh + , base::Unretained(m_positioningHelper))); +} + +void LocationProviderQt::OnPermissionGranted() +{ + RequestRefresh(); +} + +void LocationProviderQt::updatePosition(const content::Geoposition &position) +{ + DCHECK(base::MessageLoop::current() == messageLoop()); + m_lastKnownPosition = position; + NotifyCallback(position); +} + +base::MessageLoop *LocationProviderQt::messageLoop() +{ + return static_cast(content::GeolocationProvider::GetInstance())->message_loop(); +} diff --git a/src/core/location_provider_qt.h b/src/core/location_provider_qt.h new file mode 100644 index 000000000..c3e462092 --- /dev/null +++ b/src/core/location_provider_qt.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LOCATION_PROVIDER_QT_H +#define LOCATION_PROVIDER_QT_H + +#include + +#include "content/browser/geolocation/location_provider_base.h" +#include "content/public/common/geoposition.h" + +QT_FORWARD_DECLARE_CLASS(QThread) +class QtPositioningHelper; + +namespace base { +class MessageLoop; +} + +class LocationProviderQt : public content::LocationProviderBase +{ +public: + LocationProviderQt(); + virtual ~LocationProviderQt(); + + // LocationProviderBase + virtual bool StartProvider(bool highAccuracy) Q_DECL_OVERRIDE; + virtual void StopProvider() Q_DECL_OVERRIDE; + virtual void GetPosition(content::Geoposition *position) Q_DECL_OVERRIDE { *position = m_lastKnownPosition; } + virtual void RequestRefresh() Q_DECL_OVERRIDE; + virtual void OnPermissionGranted() Q_DECL_OVERRIDE; + +private: + friend class QtPositioningHelper; + + static base::MessageLoop *messageLoop(); + void updatePosition(const content::Geoposition &); + + content::Geoposition m_lastKnownPosition; + QtPositioningHelper *m_positioningHelper; +}; +//#define QT_USE_POSITIONING 1 + +#endif // LOCATION_PROVIDER_QT_H diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h index 9d9cdd675..be59c97b8 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -135,6 +135,10 @@ inline QDateTime toQt(base::Time time) return QDateTime::fromMSecsSinceEpoch(time.ToJavaTime()); } +inline base::Time toTime(const QDateTime &dateTime) { + return base::Time::FromInternalValue(dateTime.toMSecsSinceEpoch()); +} + inline base::FilePath::StringType toFilePathString(const QString &str) { #if defined(OS_WIN) diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index dd9f800db..678b558c1 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -730,6 +730,12 @@ void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin, MediaCaptureDevicesDispatcher::GetInstance()->handleMediaAccessPermissionResponse(d->webContents.get(), securityOrigin, flags); } +void WebContentsAdapter::runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed) +{ + Q_D(WebContentsAdapter); + d->webContentsDelegate->m_lastGeolocationRequestCallbacks.first.Run(allowed); +} + void WebContentsAdapter::dpiScaleChanged() { Q_D(WebContentsAdapter); diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 6e17fc2f5..18542d039 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -109,6 +109,7 @@ public: void wasShown(); void wasHidden(); void grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags); + void runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed); void dpiScaleChanged(); QAccessibleInterface *browserAccessible(); diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 8fd988c7e..df2039ba6 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -172,6 +172,7 @@ public: virtual QObject *accessibilityParentObject() = 0; virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) = 0; virtual void authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword) = 0; + virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) = 0; virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) = 0; virtual WebEngineSettings *webEngineSettings() const = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index f9dba67fe..46830f865 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -301,3 +301,9 @@ void WebContentsDelegateQt::allowCertificateError(const QExplicitlySharedDataPoi { m_viewClient->allowCertificateError(errorController); } + +void WebContentsDelegateQt::requestGeolocationPermission(const GURL &requestingFrameOrigin, base::Callback resultCallback, base::Closure *cancelCallback) +{ + m_lastGeolocationRequestCallbacks = qMakePair(resultCallback, cancelCallback); + m_viewClient->runGeolocationPermissionRequest(toQt(requestingFrameOrigin)); +} diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 2ab5fc8cd..29a548f47 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -40,6 +40,8 @@ #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" +#include "base/callback.h" + #include "javascript_dialog_manager_qt.h" #include @@ -88,7 +90,9 @@ public: void overrideWebPreferences(content::WebContents *, WebPreferences*); void allowCertificateError(const QExplicitlySharedDataPointer &) ; + void requestGeolocationPermission(const GURL &requestingFrameOrigin, base::Callback resultCallback, base::Closure *cancelCallback); + QPair, base::Closure*> m_lastGeolocationRequestCallbacks; private: WebContentsAdapter *createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index c7ea6575e..7deba4ce7 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -178,6 +178,7 @@ public: virtual QObject *accessibilityParentObject() Q_DECL_OVERRIDE; virtual WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE; virtual void allowCertificateError(const QExplicitlySharedDataPointer &errorController); + virtual void runGeolocationPermissionRequest(QUrl const&) Q_DECL_OVERRIDE { } virtual BrowserContextAdapter *browserContextAdapter() Q_DECL_OVERRIDE; diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index e3ab2ec0d..3f5fd53b5 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -343,6 +343,12 @@ void QWebEnginePagePrivate::runMediaAccessPermissionRequest(const QUrl &security Q_EMIT q->featurePermissionRequested(securityOrigin, requestedFeature); } +void QWebEnginePagePrivate::runGeolocationPermissionRequest(const QUrl &securityOrigin) +{ + Q_Q(QWebEnginePage); + Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::Geolocation); +} + QObject *QWebEnginePagePrivate::accessibilityParentObject() { return view; @@ -756,6 +762,8 @@ QMenu *QWebEnginePage::createStandardContextMenu() void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEnginePage::Feature feature, QWebEnginePage::PermissionPolicy policy) { Q_D(QWebEnginePage); + if (policy == PermissionUnknown) + return; WebContentsAdapterClient::MediaRequestFlags flags = WebContentsAdapterClient::MediaNone; switch (feature) { case MediaAudioVideoCapture: @@ -774,6 +782,10 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine } d->adapter->grantMediaAccessPermission(securityOrigin, flags); } + d->adapter->grantMediaAccessPermission(securityOrigin, flags); + break; + case QWebEnginePage::Geolocation: + d->adapter->runGeolocationRequestCallback(securityOrigin, (policy == PermissionGrantedByUser) ? true : false); break; default: break; diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 6424c3b0b..23d577c94 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -135,6 +135,7 @@ public: virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE; virtual void authenticationRequired(const QUrl &requestUrl, const QString &realm, bool isProxy, const QString &challengingHost, QString *outUser, QString *outPassword) Q_DECL_OVERRIDE; virtual void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) Q_DECL_OVERRIDE; + virtual void runGeolocationPermissionRequest(const QUrl &securityOrigin) Q_DECL_OVERRIDE; virtual QObject *accessibilityParentObject() Q_DECL_OVERRIDE; virtual WebEngineSettings *webEngineSettings() const Q_DECL_OVERRIDE; virtual void allowCertificateError(const QExplicitlySharedDataPointer &controller) Q_DECL_OVERRIDE; -- cgit v1.2.3