summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Rossi <pierre.rossi@digia.com>2014-09-18 18:21:28 +0200
committerPierre Rossi <pierre.rossi@gmail.com>2014-11-24 13:23:12 +0100
commita029fa2f6ef08bcad653f3d3e5a53ca8e3340b14 (patch)
tree446d7e2eee03aed3886246f11622bb7fc47b6b6b
parent66b2ca886063cfecaf000578492aa360581cab8a (diff)
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 <andras.becsi@digia.com>
m---------src/3rdparty0
-rw-r--r--src/core/access_token_store_qt.cpp50
-rw-r--r--src/core/access_token_store_qt.h38
-rw-r--r--src/core/content_browser_client_qt.cpp38
-rw-r--r--src/core/content_browser_client_qt.h12
-rw-r--r--src/core/core_gyp_generator.pro9
-rw-r--r--src/core/core_module.pro1
-rw-r--r--src/core/location_provider_qt.cpp248
-rw-r--r--src/core/location_provider_qt.h76
-rw-r--r--src/core/type_conversion.h4
-rw-r--r--src/core/web_contents_adapter.cpp6
-rw-r--r--src/core/web_contents_adapter.h1
-rw-r--r--src/core/web_contents_adapter_client.h1
-rw-r--r--src/core/web_contents_delegate_qt.cpp6
-rw-r--r--src/core/web_contents_delegate_qt.h4
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h1
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp12
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h1
18 files changed, 487 insertions, 21 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 0dcd4e35086a90f643bb721fad1ef786f5fff8b
+Subproject 66388297cf2ca42049fb099237134ec33465e2f
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 <QtCore/qcompilerdetection.h>
+#include <QtCore/QFile>
+#include <QtCore/QScopedPointer>
+
+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<void(bool)> result_callback,
- base::Closure *cancel_callback)
+void ContentBrowserClientQt::RequestGeolocationPermission(content::WebContents *webContents, int /*bridgeId*/, const GURL &requestingFrameOrigin, bool /*userGesture*/, base::Callback<void (bool)> resultCallback, base::Closure *cancelCallback)
+{
+ WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(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<void(bool)>& 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<void(bool)> result_callback,
- base::Closure *cancel_callback) Q_DECL_OVERRIDE;
+ void RequestGeolocationPermission(content::WebContents* web_contents, int, const GURL& requesting_frame
+ , bool, base::Callback<void(bool)> 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 <math.h>
+
+#include "type_conversion.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QThread>
+#include <QtPositioning/QGeoPositionInfoSource>
+
+#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<void (QGeoPositionInfoSource::*)(QGeoPositionInfoSource::Error)>(&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::GeolocationProviderImpl*>(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 <QtCore/qcompilerdetection.h>
+
+#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<void (bool)> 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 <QtCore/qcompilerdetection.h>
@@ -88,7 +90,9 @@ public:
void overrideWebPreferences(content::WebContents *, WebPreferences*);
void allowCertificateError(const QExplicitlySharedDataPointer<CertificateErrorController> &) ;
+ void requestGeolocationPermission(const GURL &requestingFrameOrigin, base::Callback<void (bool)> resultCallback, base::Closure *cancelCallback);
+ QPair<base::Callback<void (bool)>, 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<CertificateErrorController> &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<CertificateErrorController> &controller) Q_DECL_OVERRIDE;