summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKirill Burtsev <kirill.burtsev@qt.io>2019-01-31 13:08:21 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-06 15:18:18 +0000
commitf4ca67aa7f70f58d39ef8689ddd5910e215ed6cd (patch)
treeebb9937672b14c725de14fd7da6e3eeac269e861 /src
parent7aa06a1614b7ca6508d96ee2e8ef0f4c49038a6f (diff)
Web Notifications API
Implements API for end-user notifications. Co-authored by Allan Sandfeld Jensen [ChangeLog][Profile] Support for Web Notifications API for end-user notifications through QWebEngineNotification Task-number: QTBUG-50995 Fixes: QTBUG-51191 Change-Id: Icebaaa05275a713e801f1f8ecdaaec725fa264c8 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src')
m---------src/3rdparty0
-rw-r--r--src/core/api/core_api.pro2
-rw-r--r--src/core/api/qwebenginenotification.cpp275
-rw-r--r--src/core/api/qwebenginenotification.h112
-rw-r--r--src/core/content_browser_client_qt.cpp10
-rw-r--r--src/core/content_browser_client_qt.h2
-rw-r--r--src/core/core_chromium.pri4
-rw-r--r--src/core/permission_manager_qt.cpp8
-rw-r--r--src/core/platform_notification_service_qt.cpp208
-rw-r--r--src/core/platform_notification_service_qt.h92
-rw-r--r--src/core/profile_adapter.h14
-rw-r--r--src/core/profile_adapter_client.h4
-rw-r--r--src/core/profile_qt.cpp1
-rw-r--r--src/core/user_notification_controller.cpp219
-rw-r--r--src/core/user_notification_controller.h114
-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.cpp5
-rw-r--r--src/core/web_contents_delegate_qt.h1
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp23
-rw-r--r--src/webengine/api/qquickwebengineprofile.h3
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h2
-rw-r--r--src/webengine/api/qquickwebengineview.cpp9
-rw-r--r--src/webengine/api/qquickwebengineview_p.h3
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h1
-rw-r--r--src/webengine/doc/src/qtwebengine-features.qdoc10
-rw-r--r--src/webengine/doc/src/webengineview_lgpl.qdoc2
-rw-r--r--src/webengine/plugin/plugin.cpp3
-rw-r--r--src/webenginewidgets/api/qwebenginenotificationpresenter.cpp101
-rw-r--r--src/webenginewidgets/api/qwebenginenotificationpresenter_p.h83
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp10
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h2
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h1
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp30
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.h6
-rw-r--r--src/webenginewidgets/api/qwebengineprofile_p.h6
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc2
-rw-r--r--src/webenginewidgets/webenginewidgets.pro2
39 files changed, 1369 insertions, 9 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 5a76a0a325a041dab3c93943c99835d3e929762
+Subproject 8d510183ca27142801b56bb50d63cbb2a92d433
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index b5bb93847..d6ef81add 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -38,6 +38,7 @@ HEADERS = \
qwebenginecookiestore.h \
qwebenginecookiestore_p.h \
qwebenginehttprequest.h \
+ qwebenginenotification.h \
qwebenginequotarequest.h \
qwebengineregisterprotocolhandlerrequest.h \
qwebengineurlrequestinterceptor.h \
@@ -51,6 +52,7 @@ SOURCES = \
qtwebenginecoreglobal.cpp \
qwebenginecookiestore.cpp \
qwebenginehttprequest.cpp \
+ qwebenginenotification.cpp \
qwebenginequotarequest.cpp \
qwebengineregisterprotocolhandlerrequest.cpp \
qwebengineurlrequestinfo.cpp \
diff --git a/src/core/api/qwebenginenotification.cpp b/src/core/api/qwebenginenotification.cpp
new file mode 100644
index 000000000..0b91cf273
--- /dev/null
+++ b/src/core/api/qwebenginenotification.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebenginenotification.h"
+
+#include "user_notification_controller.h"
+
+#include <QExplicitlySharedDataPointer>
+
+QT_BEGIN_NAMESPACE
+
+using QtWebEngineCore::UserNotificationController;
+
+/*!
+ \class QWebEngineNotification
+ \brief The QWebEngineNotification class encapsulates the data of an HTML5 web notification.
+ \since 5.13
+
+ \inmodule QtWebEngineCore
+
+ This class contains the information and API for HTML5 desktop and push notifications.
+*/
+
+class QWebEngineNotificationPrivate : public UserNotificationController::Client {
+public:
+ QWebEngineNotificationPrivate(QWebEngineNotification *q, const QSharedPointer<UserNotificationController> &controller)
+ : controller(controller)
+ , q(q)
+ {
+ controller->setClient(this);
+ }
+ ~QWebEngineNotificationPrivate() override
+ {
+ if (controller->client() == this)
+ controller->setClient(0);
+ }
+
+ // UserNotificationController::Client:
+ virtual void notificationClosed(const UserNotificationController *) Q_DECL_OVERRIDE
+ {
+ Q_EMIT q->closed();
+ }
+
+ QSharedPointer<UserNotificationController> controller;
+ QWebEngineNotification *q;
+};
+
+
+/*!
+ Creates a null QWebEngineNotification.
+
+ \sa isNull()
+*/
+QWebEngineNotification::QWebEngineNotification() { }
+
+/*! \internal
+*/
+QWebEngineNotification::QWebEngineNotification(const QSharedPointer<UserNotificationController> &controller)
+ : d_ptr(new QWebEngineNotificationPrivate(this, controller))
+{ }
+
+/*! \internal
+*/
+QWebEngineNotification::QWebEngineNotification(const QWebEngineNotification &other)
+ : QObject()
+ , d_ptr(new QWebEngineNotificationPrivate(this, other.d_ptr->controller))
+{ }
+
+/*! \internal
+*/
+QWebEngineNotification::~QWebEngineNotification()
+{
+}
+
+/*! \internal
+*/
+const QWebEngineNotification &QWebEngineNotification::operator=(const QWebEngineNotification &other)
+{
+ d_ptr.reset(new QWebEngineNotificationPrivate(this, other.d_ptr->controller));
+ return *this;
+}
+
+/*!
+ Returns \c true if the two notifications belong to the same message chain.
+ That is, if their tag() and origin() are the same. This means one is
+ a replacement or an update of the \a other.
+
+ \sa tag(), origin()
+*/
+bool QWebEngineNotification::matches(const QWebEngineNotification &other) const
+{
+ if (!d_ptr)
+ return !other.d_ptr;
+ if (!other.d_ptr)
+ return false;
+ return tag() == other.tag() && origin() == other.origin();
+}
+
+/*!
+ \property QWebEngineNotification::title
+ \brief The title of the notification.
+ \sa message()
+*/
+QString QWebEngineNotification::title() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->title() : QString();
+}
+
+/*!
+ \property QWebEngineNotification::message
+ \brief The body of the notification message.
+ \sa title()
+*/
+
+QString QWebEngineNotification::message() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->body() : QString();
+}
+
+/*!
+ \property QWebEngineNotification::tag
+ \brief The tag of the notification message.
+
+ New notifications that have the same tag and origin URL as an existing
+ one should replace or update the old notification with the same tag.
+
+ \sa matches()
+*/
+QString QWebEngineNotification::tag() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->tag() : QString();
+}
+
+/*!
+ \property QWebEngineNotification::origin
+ \brief The URL of the page sending the notification.
+*/
+
+QUrl QWebEngineNotification::origin() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->origin() : QUrl();
+}
+
+/*!
+ \property QWebEngineNotification::icon
+ \brief The icon to be shown with the notification.
+
+ If no icon is set by the sender, an null QIcon is returned.
+*/
+QIcon QWebEngineNotification::icon() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->icon() : QIcon();
+}
+
+/*!
+ \property QWebEngineNotification::language
+ \brief The primary language for the notification's title and body.
+
+ Its value is a valid BCP 47 language tag, or the empty string.
+
+ \sa title(), message()
+*/
+QString QWebEngineNotification::language() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? d->controller->language() : QString();
+}
+
+/*!
+ \property QWebEngineNotification::direction
+ \brief The text direction for the notification's title and body.
+ \sa title(), message()
+*/
+QWebEngineNotification::Direction QWebEngineNotification::direction() const
+{
+ Q_D(const QWebEngineNotification);
+ return d ? static_cast<Direction>(d->controller->direction()) : DirectionAuto;
+}
+
+/*!
+ Returns \c true if the notification is a default constructed null notification.
+*/
+bool QWebEngineNotification::isNull() const
+{
+ return d_ptr.isNull();
+}
+
+/*!
+ Creates and dispatches a JavaScript \e {show event} on notification.
+
+ Should be called by the notification platform when the notification has been shown to user.
+*/
+void QWebEngineNotification::show() const
+{
+ Q_D(const QWebEngineNotification);
+ if (d)
+ d->controller->notificationDisplayed();
+}
+
+/*!
+ Creates and dispatches a JavaScript \e {click event} on notification.
+
+ Should be called by the notification platform when the notification is activated by the user.
+*/
+void QWebEngineNotification::click() const
+{
+ Q_D(const QWebEngineNotification);
+ if (d)
+ d->controller->notificationClicked();
+}
+
+/*!
+ Creates and dispatches a JavaScript \e {close event} on notification.
+
+ Should be called by the notification platform when the notification is closed,
+ either by the underlying platform or by the user.
+*/
+void QWebEngineNotification::close() const
+{
+ Q_D(const QWebEngineNotification);
+ if (d)
+ d->controller->notificationClosed();
+}
+
+/*!
+ \fn void QWebEngineNotification::closed()
+
+ This signal is emitted when the web page calls close steps for the notification,
+ and it no longer needs to be shown.
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qwebenginenotification.cpp"
diff --git a/src/core/api/qwebenginenotification.h b/src/core/api/qwebenginenotification.h
new file mode 100644
index 000000000..b6b7414f9
--- /dev/null
+++ b/src/core/api/qwebenginenotification.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINENOTIFICATION_H
+#define QWEBENGINENOTIFICATION_H
+
+#include <QtWebEngineCore/qtwebenginecoreglobal.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QUrl>
+#include <QtGui/QIcon>
+
+namespace QtWebEngineCore {
+class UserNotificationController;
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWebEngineNotificationPrivate;
+
+class QWEBENGINECORE_EXPORT QWebEngineNotification : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QUrl origin READ origin CONSTANT FINAL)
+ Q_PROPERTY(QIcon icon READ icon CONSTANT FINAL)
+ Q_PROPERTY(QString title READ title CONSTANT FINAL)
+ Q_PROPERTY(QString message READ message CONSTANT FINAL)
+ Q_PROPERTY(QString tag READ tag CONSTANT FINAL)
+ Q_PROPERTY(QString language READ language CONSTANT FINAL)
+ Q_PROPERTY(Direction direction READ direction CONSTANT FINAL)
+
+public:
+ QWebEngineNotification();
+ QWebEngineNotification(const QWebEngineNotification &);
+ virtual ~QWebEngineNotification();
+ const QWebEngineNotification &operator=(const QWebEngineNotification &);
+
+ enum Direction {
+ LeftToRight = Qt::LeftToRight,
+ RightToLeft = Qt::RightToLeft,
+ DirectionAuto = Qt::LayoutDirectionAuto
+ };
+ Q_ENUM(Direction)
+
+ bool matches(const QWebEngineNotification &) const;
+
+ QUrl origin() const;
+ QIcon icon() const;
+ QString title() const;
+ QString message() const;
+ QString tag() const;
+ QString language() const;
+ Direction direction() const;
+
+ bool isNull() const;
+
+public Q_SLOTS:
+ void show() const;
+ void click() const;
+ void close() const;
+
+Q_SIGNALS:
+ void closed();
+
+private:
+ QWebEngineNotification(const QSharedPointer<QtWebEngineCore::UserNotificationController> &);
+ Q_DECLARE_PRIVATE(QWebEngineNotification)
+ QScopedPointer<QWebEngineNotificationPrivate> d_ptr;
+ friend class QQuickWebEngineProfilePrivate;
+ friend class QWebEngineProfilePrivate;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINENOTIFICATION_H
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp
index 3861d1c95..a9959a82b 100644
--- a/src/core/content_browser_client_qt.cpp
+++ b/src/core/content_browser_client_qt.cpp
@@ -103,6 +103,7 @@
#include "media_capture_devices_dispatcher.h"
#include "net/network_delegate_qt.h"
#include "net/url_request_context_getter_qt.h"
+#include "platform_notification_service_qt.h"
#if QT_CONFIG(webengine_printing_and_pdf)
#include "printing/printing_message_filter_qt.h"
#endif
@@ -454,7 +455,7 @@ void ContentBrowserClientQt::GetAdditionalMappedFilesForChildProcess(const base:
void ContentBrowserClientQt::DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host)
{
browser_host->GetPpapiHost()->AddHostFactoryFilter(
- base::WrapUnique(new QtWebEngineCore::PepperHostFactoryQt(browser_host)));
+ std::make_unique<QtWebEngineCore::PepperHostFactoryQt>(browser_host));
}
#endif
@@ -463,6 +464,13 @@ content::DevToolsManagerDelegate* ContentBrowserClientQt::GetDevToolsManagerDele
return new DevToolsManagerDelegateQt;
}
+content::PlatformNotificationService *ContentBrowserClientQt::GetPlatformNotificationService()
+{
+ if (!m_platformNotificationService)
+ m_platformNotificationService = std::make_unique<PlatformNotificationServiceQt>();
+ return m_platformNotificationService.get();
+}
+
// This is a really complicated way of doing absolutely nothing, but Mojo demands it:
class ServiceDriver
: public blink::mojom::InsecureInputService
diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h
index fc938f882..403ff3a9d 100644
--- a/src/core/content_browser_client_qt.h
+++ b/src/core/content_browser_client_qt.h
@@ -108,6 +108,7 @@ public:
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(content::ResourceContext *resource_context) override;
content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() override;
+ content::PlatformNotificationService *GetPlatformNotificationService() override;
std::string GetApplicationLocale() override;
std::string GetAcceptLangs(content::BrowserContext* context) override;
@@ -210,6 +211,7 @@ private:
BrowserMainPartsQt* m_browserMainParts;
std::unique_ptr<content::ResourceDispatcherHostDelegate> m_resourceDispatcherHostDelegate;
+ std::unique_ptr<content::PlatformNotificationService> m_platformNotificationService;
scoped_refptr<ShareGroupQtQuick> m_shareGroupQtQuick;
std::unique_ptr<service_manager::BinderRegistry> m_frameInterfaces;
std::unique_ptr<service_manager::BinderRegistryWithArgs<content::RenderFrameHost*>> m_frameInterfacesParameterized;
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index edf6806a3..aa595036d 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -98,6 +98,7 @@ SOURCES = \
ozone/platform_window_qt.cpp \
ozone/surface_factory_qt.cpp \
permission_manager_qt.cpp \
+ platform_notification_service_qt.cpp \
process_main.cpp \
profile_adapter.cpp \
profile_adapter_client.cpp \
@@ -123,6 +124,7 @@ SOURCES = \
touch_selection_controller_client_qt.cpp \
touch_selection_menu_controller.cpp \
type_conversion.cpp \
+ user_notification_controller.cpp \
user_script.cpp \
visited_links_manager_qt.cpp \
web_contents_adapter.cpp \
@@ -201,6 +203,7 @@ HEADERS = \
ozone/platform_window_qt.h \
ozone/surface_factory_qt.h \
permission_manager_qt.h \
+ platform_notification_service_qt.h \
process_main.h \
profile_adapter.h \
profile_adapter_client.h \
@@ -230,6 +233,7 @@ HEADERS = \
touch_selection_controller_client_qt.h \
touch_selection_menu_controller.h \
type_conversion.h \
+ user_notification_controller.h \
user_script.h \
visited_links_manager_qt.h \
web_contents_adapter.h \
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index cf3041e7a..2a7311187 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -61,8 +61,9 @@ ProfileAdapter::PermissionType toQt(content::PermissionType type)
return ProfileAdapter::AudioCapturePermission;
case content::PermissionType::VIDEO_CAPTURE:
return ProfileAdapter::VideoCapturePermission;
- case content::PermissionType::FLASH:
case content::PermissionType::NOTIFICATIONS:
+ return ProfileAdapter::NotificationPermission;
+ case content::PermissionType::FLASH:
case content::PermissionType::MIDI_SYSEX:
case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER:
case content::PermissionType::MIDI:
@@ -188,6 +189,9 @@ int PermissionManagerQt::RequestPermission(content::PermissionType permission,
m_requests.insert(request_id, request);
if (permissionType == ProfileAdapter::GeolocationPermission)
contentsDelegate->requestGeolocationPermission(request.origin);
+ else if (permissionType == ProfileAdapter::NotificationPermission)
+ contentsDelegate->requestUserNotificationPermission(request.origin);
+
return request_id;
}
@@ -236,6 +240,8 @@ int PermissionManagerQt::RequestPermissions(const std::vector<content::Permissio
const ProfileAdapter::PermissionType permissionType = toQt(permission);
if (permissionType == ProfileAdapter::GeolocationPermission)
contentsDelegate->requestGeolocationPermission(request.origin);
+ else if (permissionType == ProfileAdapter::NotificationPermission)
+ contentsDelegate->requestUserNotificationPermission(request.origin);
}
return request_id;
}
diff --git a/src/core/platform_notification_service_qt.cpp b/src/core/platform_notification_service_qt.cpp
new file mode 100644
index 000000000..dff3aed61
--- /dev/null
+++ b/src/core/platform_notification_service_qt.cpp
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "platform_notification_service_qt.h"
+
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/permission_type.h"
+#include "content/public/browser/notification_event_dispatcher.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
+
+#include "profile_adapter.h"
+#include "profile_adapter_client.h"
+#include "profile_qt.h"
+#include "user_notification_controller.h"
+#include "resource_context_qt.h"
+#include "type_conversion.h"
+
+#include <QSharedPointer>
+
+namespace QtWebEngineCore {
+
+struct NonPersistentNotificationDelegate : UserNotificationController::Delegate {
+ NonPersistentNotificationDelegate(const std::string &id) : notification_id(id) { }
+
+ virtual void shown() override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNonPersistentShowEvent(notification_id);
+ }
+
+ virtual void clicked() override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNonPersistentClickEvent(notification_id, base::DoNothing());
+ }
+
+ virtual void closed(bool /*by_user*/) override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNonPersistentCloseEvent(notification_id, base::DoNothing());
+ }
+
+ const std::string notification_id;
+};
+
+struct PersistentNotificationDelegate : UserNotificationController::Delegate {
+ PersistentNotificationDelegate(content::BrowserContext *context, const std::string &id, const GURL &origin)
+ : browser_context(context), notification_id(id), origin(origin) { }
+
+ virtual void shown() override { }
+
+ virtual void clicked() override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNotificationClickEvent(browser_context, notification_id, origin, base::nullopt, base::nullopt, base::DoNothing());
+ }
+
+ virtual void closed(bool by_user) override {
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (auto inst = content::NotificationEventDispatcher::GetInstance())
+ inst->DispatchNotificationCloseEvent(browser_context, notification_id, origin, by_user, base::DoNothing());
+ }
+
+ content::BrowserContext *browser_context;
+ const std::string notification_id;
+ const GURL origin;
+};
+
+
+PlatformNotificationServiceQt::PlatformNotificationServiceQt() {}
+
+PlatformNotificationServiceQt::~PlatformNotificationServiceQt() {}
+
+void PlatformNotificationServiceQt::DisplayNotification(
+ content::BrowserContext *browser_context,
+ const std::string &notification_id,
+ const GURL &origin,
+ const blink::PlatformNotificationData &notificationData,
+ const blink::NotificationResources &notificationResources)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt *profile = static_cast<ProfileQt*>(browser_context);
+
+ auto delegate = new NonPersistentNotificationDelegate(notification_id);
+ QSharedPointer<UserNotificationController> controller(
+ new UserNotificationController(notificationData, notificationResources, origin, delegate));
+
+ profile->profileAdapter()->ephemeralNotifications().insert(QByteArray::fromStdString(notification_id), controller);
+
+ const QList<ProfileAdapterClient *> clients = profile->profileAdapter()->clients();
+ for (ProfileAdapterClient *client : clients)
+ client->showNotification(controller);
+}
+
+void PlatformNotificationServiceQt::DisplayPersistentNotification(
+ content::BrowserContext *browser_context,
+ const std::string &notification_id,
+ const GURL &service_worker_origin,
+ const GURL &origin,
+ const blink::PlatformNotificationData &notificationData,
+ const blink::NotificationResources &notificationResources)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt * profile = static_cast<ProfileQt*>(browser_context);
+
+ auto delegate = new PersistentNotificationDelegate(profile, notification_id, service_worker_origin);
+ QSharedPointer<UserNotificationController> controller(
+ new UserNotificationController(notificationData, notificationResources, service_worker_origin, delegate));
+
+ profile->profileAdapter()->persistentNotifications().insert(QByteArray::fromStdString(notification_id), controller);
+ const QList<ProfileAdapterClient *> clients = profile->profileAdapter()->clients();
+ for (ProfileAdapterClient *client : clients)
+ client->showNotification(controller);
+}
+
+void PlatformNotificationServiceQt::CloseNotification(
+ content::BrowserContext *browser_context,
+ const std::string &notification_id)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt *profile = static_cast<ProfileQt*>(browser_context);
+
+ QSharedPointer<UserNotificationController> notificationController =
+ profile->profileAdapter()->ephemeralNotifications().take(QByteArray::fromStdString(notification_id)).lock();
+ if (notificationController)
+ notificationController->closeNotification();
+}
+
+void PlatformNotificationServiceQt::ClosePersistentNotification(
+ content::BrowserContext *browser_context,
+ const std::string &notification_id)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt *profile = static_cast<ProfileQt*>(browser_context);
+
+ QSharedPointer<UserNotificationController> notificationController =
+ profile->profileAdapter()->persistentNotifications().take(QByteArray::fromStdString(notification_id));
+ if (notificationController)
+ notificationController->closeNotification();
+}
+
+void PlatformNotificationServiceQt::GetDisplayedNotifications(
+ content::BrowserContext *browser_context,
+ const DisplayedNotificationsCallback &callback)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ ProfileQt *profile = static_cast<ProfileQt *>(browser_context);
+
+ std::unique_ptr<std::set<std::string>> movableStdStringSet = std::make_unique<std::set<std::string>>();
+ auto it = profile->profileAdapter()->persistentNotifications().constBegin();
+ const auto end = profile->profileAdapter()->persistentNotifications().constEnd();
+ while (it != end) {
+ if (it.value()->isShown())
+ movableStdStringSet->insert(it.key().toStdString());
+ ++it;
+ }
+
+ callback.Run(std::move(movableStdStringSet), true /* supports_synchronization */);
+}
+
+int64_t PlatformNotificationServiceQt::ReadNextPersistentNotificationId(content::BrowserContext *browser_context)
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ auto prefs = static_cast<ProfileQt *>(browser_context)->GetPrefs();
+ int64_t nextId = prefs->GetInteger(prefs::kNotificationNextPersistentId) + 1;
+ prefs->SetInt64(prefs::kNotificationNextPersistentId, nextId);
+ return nextId;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/platform_notification_service_qt.h b/src/core/platform_notification_service_qt.h
new file mode 100644
index 000000000..66cee9ed0
--- /dev/null
+++ b/src/core/platform_notification_service_qt.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PLATFORM_NOTIFICATION_SERVICE_QT_H
+#define PLATFORM_NOTIFICATION_SERVICE_QT_H
+
+#include "content/public/browser/platform_notification_service.h"
+
+namespace QtWebEngineCore {
+
+class PlatformNotificationServiceQt : public content::PlatformNotificationService {
+public:
+ PlatformNotificationServiceQt();
+ ~PlatformNotificationServiceQt() override;
+
+ // Displays the notification described in |notification_data| to the user. A
+ // closure through which the notification can be closed will be stored in the
+ // |cancel_callback| argument. This method must be called on the UI thread.
+ void DisplayNotification(content::BrowserContext* browser_context,
+ const std::string& notification_id,
+ const GURL& origin,
+ const blink::PlatformNotificationData& notificationData,
+ const blink::NotificationResources& notificationResources) override;
+
+ // Displays the persistent notification described in |notification_data| to
+ // the user. This method must be called on the UI thread.
+ void DisplayPersistentNotification(content::BrowserContext* browser_context,
+ const std::string& notification_id,
+ const GURL& service_worker_origin,
+ const GURL& origin,
+ const blink::PlatformNotificationData& notification_data,
+ const blink::NotificationResources& notification_resources) override;
+
+ // Closes the notification identified by |notification_id|.
+ // This method must be called on the UI thread.
+ void CloseNotification(content::BrowserContext* browser_context, const std::string& notification_id) override;
+
+ // Closes the persistent notification identified by |persistent_notification_id|.
+ // This method must be called on the UI thread.
+ void ClosePersistentNotification(content::BrowserContext* browser_context, const std::string& notification_id) override;
+
+ // Retrieves the ids of all currently displaying notifications and
+ // posts |callback| with the result.
+ void GetDisplayedNotifications(content::BrowserContext* browser_context, const DisplayedNotificationsCallback& callback) override;
+
+ // Reads the value of the next persistent notification ID from the profile and
+ // increments the value, as it is called once per notification write.
+ virtual int64_t ReadNextPersistentNotificationId(content::BrowserContext* browser_context) override;
+
+ // Records a given notification to UKM.
+ virtual void RecordNotificationUkmEvent(content::BrowserContext*, const content::NotificationDatabaseData&) override { }
+};
+
+} // namespace QtWebEngineCore
+
+#endif // PLATFORM_NOTIFICATION_SERVICE_QT_H
diff --git a/src/core/profile_adapter.h b/src/core/profile_adapter.h
index 800058bc5..482835010 100644
--- a/src/core/profile_adapter.h
+++ b/src/core/profile_adapter.h
@@ -69,8 +69,9 @@ QT_FORWARD_DECLARE_CLASS(QObject)
namespace QtWebEngineCore {
-class ProfileAdapterClient;
+class UserNotificationController;
class DownloadManagerDelegateQt;
+class ProfileAdapterClient;
class ProfileQt;
class UserResourceControllerHost;
class VisitedLinksManagerQt;
@@ -153,8 +154,7 @@ public:
enum PermissionType {
UnsupportedPermission = 0,
GeolocationPermission = 1,
-// Reserved:
-// NotificationPermission = 2,
+ NotificationPermission = 2,
AudioCapturePermission = 3,
VideoCapturePermission = 4,
ClipboardRead = 5,
@@ -200,6 +200,11 @@ public:
void removePageRequestInterceptor();
bool hasPageRequestInterceptor() const { return m_pageRequestInterceptors > 0; }
+ QHash<QByteArray, QWeakPointer<UserNotificationController>> &ephemeralNotifications()
+ { return m_ephemeralNotifications; }
+ QHash<QByteArray, QSharedPointer<UserNotificationController>> &persistentNotifications()
+ { return m_persistentNotifications; }
+
private:
void updateCustomUrlSchemeHandlers();
void resetVisitedLinksManager();
@@ -224,6 +229,9 @@ private:
PersistentCookiesPolicy m_persistentCookiesPolicy;
VisitedLinksPolicy m_visitedLinksPolicy;
QHash<QByteArray, QPointer<QWebEngineUrlSchemeHandler>> m_customUrlSchemeHandlers;
+ QHash<QByteArray, QWeakPointer<UserNotificationController>> m_ephemeralNotifications;
+ QHash<QByteArray, QSharedPointer<UserNotificationController>> m_persistentNotifications;
+
QList<ProfileAdapterClient*> m_clients;
int m_httpCacheMaxSize;
int m_pageRequestInterceptors;
diff --git a/src/core/profile_adapter_client.h b/src/core/profile_adapter_client.h
index 4711f8bcf..0309200b4 100644
--- a/src/core/profile_adapter_client.h
+++ b/src/core/profile_adapter_client.h
@@ -52,12 +52,14 @@
#define PROFILE_ADAPTER_CLIENT_H
#include "qtwebenginecoreglobal_p.h"
+#include <QSharedPointer>
#include <QString>
#include <QUrl>
namespace QtWebEngineCore {
class WebContentsAdapterClient;
+class UserNotificationController;
class QWEBENGINECORE_PRIVATE_EXPORT ProfileAdapterClient
{
@@ -143,6 +145,8 @@ public:
virtual void downloadRequested(DownloadItemInfo &info) = 0;
virtual void downloadUpdated(const DownloadItemInfo &info) = 0;
virtual void useForGlobalCertificateVerificationChanged() {}
+ virtual void showNotification(QSharedPointer<UserNotificationController> &) { }
+
static QString downloadInterruptReasonToString(DownloadInterruptReason reason);
};
diff --git a/src/core/profile_qt.cpp b/src/core/profile_qt.cpp
index 0ede1df55..624a52f7b 100644
--- a/src/core/profile_qt.cpp
+++ b/src/core/profile_qt.cpp
@@ -106,6 +106,7 @@ ProfileQt::ProfileQt(ProfileAdapter *profileAdapter)
registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckUseSpellingService, false);
#endif // QT_CONFIG(webengine_spellchecker)
registry->RegisterBooleanPref(prefs::kShowInternalAccessibilityTree, false);
+ registry->RegisterIntegerPref(prefs::kNotificationNextPersistentId, 10000);
#if BUILDFLAG(ENABLE_EXTENSIONS)
registry->RegisterDictionaryPref(extensions::pref_names::kExtensions);
diff --git a/src/core/user_notification_controller.cpp b/src/core/user_notification_controller.cpp
new file mode 100644
index 000000000..82cb57e51
--- /dev/null
+++ b/src/core/user_notification_controller.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "user_notification_controller.h"
+
+#include "type_conversion.h"
+
+#include "base/callback.h"
+#include "content/public/browser/notification_event_dispatcher.h"
+#include "third_party/blink/public/common/notifications/notification_resources.h"
+#include "third_party/blink/public/common/notifications/platform_notification_data.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
+
+#include <memory>
+
+namespace QtWebEngineCore {
+
+static Qt::LayoutDirection toDirection(blink::PlatformNotificationData::Direction direction)
+{
+ switch (direction) {
+ case blink::PlatformNotificationData::DIRECTION_LEFT_TO_RIGHT:
+ return Qt::LeftToRight;
+ case blink::PlatformNotificationData::DIRECTION_RIGHT_TO_LEFT:
+ return Qt::RightToLeft;
+ case blink::PlatformNotificationData::DIRECTION_AUTO:
+ default:
+ break;
+ }
+ return Qt::LayoutDirectionAuto;
+}
+
+class UserNotificationControllerPrivate {
+public:
+ UserNotificationControllerPrivate(const blink::PlatformNotificationData &params,
+ const blink::NotificationResources &resources,
+ const GURL &origin)
+ : m_params(params)
+ , m_origin(origin)
+ , m_delegate(nullptr)
+ , m_resources(resources)
+ , m_client(nullptr)
+ , m_iconGenerated(false)
+ , m_imageGenerated(false)
+ , m_badgeGenerated(false)
+ , m_shown(false)
+ { }
+
+ blink::PlatformNotificationData m_params;
+ GURL m_origin;
+ std::unique_ptr<UserNotificationController::Delegate> m_delegate;
+ blink::NotificationResources m_resources;
+ UserNotificationController::Client *m_client;
+ QIcon m_icon;
+ QImage m_image;
+ QImage m_badge;
+ bool m_iconGenerated;
+ bool m_imageGenerated;
+ bool m_badgeGenerated;
+ bool m_shown;
+};
+
+
+UserNotificationController::UserNotificationController(const blink::PlatformNotificationData &params,
+ const blink::NotificationResources &resources,
+ const GURL &origin,
+ Delegate *delegate)
+ : d(new UserNotificationControllerPrivate(params, resources, origin))
+{
+ d->m_delegate.reset(delegate);
+}
+
+UserNotificationController::~UserNotificationController()
+{
+ delete d;
+ d = nullptr;
+}
+
+void UserNotificationController::notificationDisplayed()
+{
+ if (!d->m_shown) {
+ d->m_shown = true;
+ if (d->m_delegate)
+ d->m_delegate->shown();
+ }
+}
+
+void UserNotificationController::notificationClosed()
+{
+ d->m_shown = false;
+ if (d->m_delegate)
+ d->m_delegate->closed(true);
+}
+
+void UserNotificationController::notificationClicked()
+{
+ if (d->m_delegate)
+ d->m_delegate->clicked();
+}
+
+void UserNotificationController::closeNotification()
+{
+ d->m_shown = false;
+ if (d->m_client)
+ d->m_client->notificationClosed(this);
+}
+
+void UserNotificationController::setClient(UserNotificationController::Client* client)
+{
+ d->m_client = client;
+}
+
+UserNotificationController::Client* UserNotificationController::client()
+{
+ return d->m_client;
+}
+
+QUrl UserNotificationController::origin() const
+{
+ return toQt(d->m_origin);
+}
+
+QIcon UserNotificationController::icon() const
+{
+ if (!d->m_iconGenerated) {
+ d->m_iconGenerated = true;
+ if (!d->m_resources.notification_icon.isNull()) {
+ QImage image = toQImage(d->m_resources.notification_icon);
+ if (!image.isNull())
+ d->m_icon = QIcon(QPixmap::fromImage(std::move(image), Qt::NoFormatConversion));
+ }
+ }
+ return d->m_icon;
+}
+
+QImage UserNotificationController::image() const
+{
+ if (d->m_imageGenerated)
+ return d->m_image;
+ d->m_image = toQImage(d->m_resources.image);
+ d->m_imageGenerated = true;
+ return d->m_image;
+}
+
+QImage UserNotificationController::badge() const
+{
+ if (d->m_badgeGenerated)
+ return d->m_badge;
+ d->m_badge = toQImage(d->m_resources.badge);
+ d->m_badgeGenerated = true;
+ return d->m_badge;
+}
+
+QString UserNotificationController::title() const
+{
+ return toQt(d->m_params.title);
+}
+
+QString UserNotificationController::body() const
+{
+ return toQt(d->m_params.body);
+}
+
+QString UserNotificationController::tag() const
+{
+ return toQt(d->m_params.tag);
+}
+
+QString UserNotificationController::language() const
+{
+ return toQt(d->m_params.lang);
+}
+
+Qt::LayoutDirection UserNotificationController::direction() const
+{
+ return toDirection(d->m_params.direction);
+}
+
+bool UserNotificationController::isShown() const
+{
+ return d->m_shown;
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/user_notification_controller.h b/src/core/user_notification_controller.h
new file mode 100644
index 000000000..840074843
--- /dev/null
+++ b/src/core/user_notification_controller.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DESKTOP_NOTIFICATION_CONTROLLER_H
+#define DESKTOP_NOTIFICATION_CONTROLLER_H
+
+#include "qtwebenginecoreglobal.h"
+
+#include <QtCore/QSharedPointer>
+#include <QtCore/QUrl>
+#include <QtGui/QIcon>
+
+class GURL;
+
+namespace blink {
+ struct NotificationResources;
+ struct PlatformNotificationData;
+}
+
+namespace QtWebEngineCore {
+
+class UserNotificationControllerPrivate;
+
+// Works as an accessor and owner of chromium objects related to showing desktop notifications.
+class QWEBENGINECORE_EXPORT UserNotificationController : public QEnableSharedFromThis<UserNotificationController> {
+public:
+ struct Delegate {
+ virtual ~Delegate() { }
+ virtual void shown() = 0;
+ virtual void clicked() = 0;
+ virtual void closed(bool byUser) = 0;
+ };
+
+ UserNotificationController(const blink::PlatformNotificationData &params,
+ const blink::NotificationResources &resources,
+ const GURL &origin,
+ Delegate *delegate);
+ ~UserNotificationController();
+
+ // The notification was shown.
+ void notificationDisplayed();
+
+ // The notification was closed.
+ void notificationClosed();
+
+ // The user clicked on the notification.
+ void notificationClicked();
+
+ // Chromium requests to close the notification.
+ void closeNotification();
+
+ QUrl origin() const;
+ QIcon icon() const;
+ QImage image() const;
+ QImage badge() const;
+ QString title() const;
+ QString body() const;
+ QString tag() const;
+ QString language() const;
+ Qt::LayoutDirection direction() const;
+
+ bool isShown() const;
+
+ class Client {
+ public:
+ virtual ~Client() { }
+ virtual void notificationClosed(const UserNotificationController *) = 0;
+ };
+ void setClient(Client *client);
+ Client* client();
+
+private:
+ UserNotificationControllerPrivate *d;
+};
+
+} // namespace QtWebEngineCore
+
+#endif // DESKTOP_NOTIFICATION_CONTROLLER_H
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 0c884d265..d85d34eb2 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1271,6 +1271,12 @@ void WebContentsAdapter::runGeolocationRequestCallback(const QUrl &securityOrigi
m_profileAdapter->permissionRequestReply(securityOrigin, ProfileAdapter::GeolocationPermission, allowed);
}
+void WebContentsAdapter::runUserNotificationRequestCallback(const QUrl &securityOrigin, bool allowed)
+{
+ CHECK_INITIALIZED();
+ m_profileAdapter->permissionRequestReply(securityOrigin, ProfileAdapter::NotificationPermission, allowed);
+}
+
void WebContentsAdapter::grantMouseLockPermission(bool granted)
{
CHECK_INITIALIZED();
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index b4a01fb17..c6e4f2256 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -183,6 +183,7 @@ public:
void grantMediaAccessPermission(const QUrl &securityOrigin, WebContentsAdapterClient::MediaRequestFlags flags);
void runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed);
void grantMouseLockPermission(bool granted);
+ void runUserNotificationRequestCallback(const QUrl &securityOrigin, bool allowed);
void setBackgroundColor(const QColor &color);
QAccessibleInterface *browserAccessible();
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index f4937f0d4..d155ed391 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -459,6 +459,7 @@ public:
virtual void runMouseLockPermissionRequest(const QUrl &securityOrigin) = 0;
virtual void runQuotaRequest(QWebEngineQuotaRequest) = 0;
virtual void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) = 0;
+ virtual void runUserNotificationPermissionRequest(const QUrl &securityOrigin) = 0;
virtual WebEngineSettings *webEngineSettings() const = 0;
RenderProcessTerminationStatus renderProcessExitStatus(int);
virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 963b89a3f..4fcf2944d 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -585,6 +585,11 @@ void WebContentsDelegateQt::requestGeolocationPermission(const QUrl &requestingO
m_viewClient->runGeolocationPermissionRequest(requestingOrigin);
}
+void WebContentsDelegateQt::requestUserNotificationPermission(const QUrl &requestingOrigin)
+{
+ m_viewClient->runUserNotificationPermissionRequest(requestingOrigin);
+}
+
extern WebContentsAdapterClient::NavigationType pageTransitionToNavigationType(ui::PageTransition transition);
void WebContentsDelegateQt::launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture)
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 40f585767..77f6cc389 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -148,6 +148,7 @@ public:
void allowCertificateError(const QSharedPointer<CertificateErrorController> &);
void selectClientCert(const QSharedPointer<ClientCertSelectController> &);
void requestGeolocationPermission(const QUrl &requestingOrigin);
+ void requestUserNotificationPermission(const QUrl &requestingOrigin);
void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture);
FaviconManager *faviconManager();
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 8a6c20f67..cf9dae90a 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -46,6 +46,7 @@
#include "qquickwebenginesettings_p.h"
#include "qquickwebengineview_p_p.h"
#include "qwebenginecookiestore.h"
+#include "qwebenginenotification.h"
#include <QQmlEngine>
@@ -150,6 +151,13 @@ ASSERT_ENUMS_MATCH(QQuickWebEngineDownloadItem::MimeHtmlSaveFormat, QtWebEngineC
The \a download argument holds the state of the finished download instance.
*/
+/*!
+ \fn QQuickWebEngineProfile::userNotification(QWebEngineNotification *notification)
+
+ This signal is emitted whenever there is a newly created user notification.
+ The \a notification argument holds the notification instance to query data and interact with.
+*/
+
QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(ProfileAdapter *profileAdapter)
: m_settings(new QQuickWebEngineSettings())
, m_profileAdapter(profileAdapter)
@@ -285,6 +293,14 @@ void QQuickWebEngineProfilePrivate::useForGlobalCertificateVerificationChanged()
Q_EMIT q->useForGlobalCertificateVerificationChanged();
}
+void QQuickWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller)
+{
+ Q_Q(QQuickWebEngineProfile);
+ auto notification = new QWebEngineNotification(controller);
+ QQmlEngine::setObjectOwnership(notification, QQmlEngine::JavaScriptOwnership);
+ Q_EMIT q->userNotification(notification);
+}
+
void QQuickWebEngineProfilePrivate::userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script)
{
Q_ASSERT(p && p->data);
@@ -365,6 +381,13 @@ void QQuickWebEngineProfilePrivate::userScripts_clear(QQmlListProperty<QQuickWeb
*/
/*!
+ \qmlsignal WebEngineProfile::userNotification(WebEngineNotification notification)
+
+ This signal is emitted whenever there is a newly created user notification.
+ The \a notification argument holds the notification instance to query data and interact with.
+*/
+
+/*!
Constructs a new profile with the parent \a parent.
*/
QQuickWebEngineProfile::QQuickWebEngineProfile(QObject *parent)
diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h
index f4460ba18..ce3285ec9 100644
--- a/src/webengine/api/qquickwebengineprofile.h
+++ b/src/webengine/api/qquickwebengineprofile.h
@@ -55,6 +55,7 @@ class QQuickWebEngineProfilePrivate;
class QQuickWebEngineScript;
class QQuickWebEngineSettings;
class QWebEngineCookieStore;
+class QWebEngineNotification;
class QWebEngineUrlRequestInterceptor;
class QWebEngineUrlSchemeHandler;
@@ -172,6 +173,8 @@ Q_SIGNALS:
void downloadRequested(QQuickWebEngineDownloadItem *download);
void downloadFinished(QQuickWebEngineDownloadItem *download);
+ void userNotification(QWebEngineNotification *notification);
+
private:
Q_DECLARE_PRIVATE(QQuickWebEngineProfile)
QQuickWebEngineProfile(QQuickWebEngineProfilePrivate *, QObject *parent = Q_NULLPTR);
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index d59470f46..322ec0101 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -85,6 +85,8 @@ public:
void useForGlobalCertificateVerificationChanged() override;
+ void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &controller) override;
+
// QQmlListPropertyHelpers
static void userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script);
static int userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p);
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 5e6a45924..e7b2d8c9c 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -320,6 +320,12 @@ void QQuickWebEngineViewPrivate::runGeolocationPermissionRequest(const QUrl &url
Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Geolocation);
}
+void QQuickWebEngineViewPrivate::runUserNotificationPermissionRequest(const QUrl &url)
+{
+ Q_Q(QQuickWebEngineView);
+ Q_EMIT q->featurePermissionRequested(url, QQuickWebEngineView::Notifications);
+}
+
void QQuickWebEngineViewPrivate::showColorDialog(QSharedPointer<ColorChooserController> controller)
{
Q_Q(QQuickWebEngineView);
@@ -1550,6 +1556,9 @@ void QQuickWebEngineView::grantFeaturePermission(const QUrl &securityOrigin, QQu
WebContentsAdapterClient::MediaDesktopAudioCapture |
WebContentsAdapterClient::MediaDesktopVideoCapture));
break;
+ case Notifications:
+ d_ptr->adapter->runUserNotificationRequestCallback(securityOrigin, granted);
+ break;
default:
Q_UNREACHABLE();
}
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index 3a40abf0a..c851dcb8d 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -209,7 +209,8 @@ public:
MediaAudioVideoCapture,
Geolocation,
DesktopVideoCapture,
- DesktopAudioVideoCapture
+ DesktopAudioVideoCapture,
+ Notifications,
};
Q_ENUM(Feature)
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index 4e8657651..543d7b119 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -145,6 +145,7 @@ public:
void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) override;
void selectClientCert(const QSharedPointer<ClientCertSelectController> &selectController) override;
void runGeolocationPermissionRequest(QUrl const&) override;
+ void runUserNotificationPermissionRequest(QUrl const&) override;
void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) override;
void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override;
void updateScrollPosition(const QPointF &position) override;
diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc
index 1dce17e08..64e9badb1 100644
--- a/src/webengine/doc/src/qtwebengine-features.qdoc
+++ b/src/webengine/doc/src/qtwebengine-features.qdoc
@@ -50,6 +50,7 @@
\li \l{Touch}
\li \l{View Source}
\li \l{WebRTC}
+ \li \l{Notifications}
\endlist
\section1 Audio and Video Codecs
@@ -511,4 +512,13 @@
This feature can be tested by setting up a webcam or microphone and then
opening \c https://test.webrtc.org/ in \l{WebEngine Widgets Simple Browser
Example}{Simple Browser} or \l{WebEngine Quick Nano Browser}{Nano Browser}.
+
+ \section1 Notifications
+
+ Qt WebEngine supports JavaScript Web Notification API.
+ The application has to explicitly allow the feature by using
+ QWebEnginePage::Notifications or \l{WebEngineView::Feature}
+ {WebEngineView.Notifications}.
+
+ Support for this feature was added in Qt 5.13.0.
*/
diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc
index d96aabc97..a6f2af39e 100644
--- a/src/webengine/doc/src/webengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview_lgpl.qdoc
@@ -858,6 +858,8 @@
(Added in Qt 5.10)
\value DesktopAudioVideoCapture
Both audio and video output capture. (Added in Qt 5.10)
+ \value WebEnginView.Notifications
+ Web notifications for the end-user.
\sa featurePermissionRequested(), grantFeaturePermission()
*/
diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp
index 0e63989ee..82a76760d 100644
--- a/src/webengine/plugin/plugin.cpp
+++ b/src/webengine/plugin/plugin.cpp
@@ -55,6 +55,7 @@
#include <QtWebEngine/private/qquickwebenginetouchhandleprovider_p_p.h>
#include <QtWebEngine/private/qquickwebengineview_p.h>
#include <QtWebEngine/private/qquickwebengineaction_p.h>
+#include <QtWebEngineCore/qwebenginenotification.h>
#include <QtWebEngineCore/qwebenginequotarequest.h>
#include <QtWebEngineCore/qwebengineregisterprotocolhandlerrequest.h>
@@ -161,7 +162,7 @@ public:
tr("Cannot create a separate instance of WebEngineClientCertificateSelection"));
qmlRegisterUncreatableType<QQuickWebEngineClientCertificateOption>(uri, 1, 9, "WebEngineClientCertificateOption",
tr("Cannot create a separate instance of WebEngineClientCertificateOption"));
-
+ qmlRegisterUncreatableType<QWebEngineNotification>(uri, 1, 9, "WebEngineNotification", msgUncreatableType("WebEngineNotification"));
}
private:
diff --git a/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp b/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp
new file mode 100644
index 000000000..c15a80373
--- /dev/null
+++ b/src/webenginewidgets/api/qwebenginenotificationpresenter.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebenginenotificationpresenter_p.h"
+
+#include <QSystemTrayIcon>
+
+QT_BEGIN_NAMESPACE
+
+DefaultNotificationPresenter::DefaultNotificationPresenter(QObject *parent) : QObject(parent)
+{
+#ifndef QT_NO_SYSTEMTRAYICON
+ m_systemTrayIcon = new QSystemTrayIcon(this);
+ connect(m_systemTrayIcon, &QSystemTrayIcon::messageClicked, this, &DefaultNotificationPresenter::messageClicked);
+#endif
+}
+
+DefaultNotificationPresenter::~DefaultNotificationPresenter()
+{
+}
+
+void DefaultNotificationPresenter::show(const QWebEngineNotification &notification)
+{
+ if (!m_activeNotification.isNull())
+ m_activeNotification.close();
+ m_activeNotification = notification;
+#ifndef QT_NO_SYSTEMTRAYICON
+ if (m_systemTrayIcon) {
+ m_systemTrayIcon->show();
+ QIcon icon = notification.icon();
+ if (!icon.isNull())
+ m_systemTrayIcon->showMessage(notification.title(), notification.message(), icon);
+ else
+ m_systemTrayIcon->showMessage(notification.title(), notification.message());
+ notification.show();
+ connect(&m_activeNotification, &QWebEngineNotification::closed, this, &DefaultNotificationPresenter::closeNotification);
+ }
+#endif
+}
+
+void DefaultNotificationPresenter::messageClicked()
+{
+ if (!m_activeNotification.isNull())
+ m_activeNotification.click();
+}
+
+void DefaultNotificationPresenter::closeNotification()
+{
+#ifndef QT_NO_SYSTEMTRAYICON
+ const QWebEngineNotification *canceled = static_cast<const QWebEngineNotification *>(QObject::sender());
+ if (m_systemTrayIcon && canceled->matches(m_activeNotification))
+ m_systemTrayIcon->hide();
+#endif
+}
+
+void defaultNotificationPresenter(const QWebEngineNotification &notification)
+{
+ static DefaultNotificationPresenter *presenter = nullptr;
+ if (!presenter)
+ presenter = new DefaultNotificationPresenter();
+ presenter->show(notification);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h b/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h
new file mode 100644
index 000000000..a66dbc1b2
--- /dev/null
+++ b/src/webenginewidgets/api/qwebenginenotificationpresenter_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWEBENGINENOTIFICATIONPRESENTER_P_H
+#define QWEBENGINENOTIFICATIONPRESENTER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtWebEngineCore/QWebEngineNotification>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QSystemTrayIcon;
+
+class DefaultNotificationPresenter : public QObject {
+ Q_OBJECT
+public:
+ DefaultNotificationPresenter(QObject *parent = nullptr);
+ virtual ~DefaultNotificationPresenter();
+
+ void show(const QWebEngineNotification &notification);
+
+private Q_SLOTS:
+ void messageClicked();
+ void closeNotification();
+
+private:
+ QSystemTrayIcon *m_systemTrayIcon;
+ QWebEngineNotification m_activeNotification;
+};
+
+void defaultNotificationPresenter(const QWebEngineNotification &notification);
+
+QT_END_NAMESPACE
+
+#endif // QWEBENGINENOTIFICATIONPRESENTER_P_H
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 22ef8fffe..790d802f0 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -54,6 +54,7 @@
#include "qwebenginefullscreenrequest.h"
#include "qwebenginehistory.h"
#include "qwebenginehistory_p.h"
+#include "qwebenginenotification.h"
#include "qwebengineprofile.h"
#include "qwebengineprofile_p.h"
#include "qwebenginequotarequest.h"
@@ -62,6 +63,7 @@
#include "qwebenginesettings.h"
#include "qwebengineview.h"
#include "qwebengineview_p.h"
+#include "user_notification_controller.h"
#include "render_widget_host_view_qt_delegate_widget.h"
#include "web_contents_adapter.h"
#include "web_engine_settings.h"
@@ -538,6 +540,12 @@ void QWebEnginePagePrivate::runRegisterProtocolHandlerRequest(QWebEngineRegister
Q_EMIT q->registerProtocolHandlerRequested(request);
}
+void QWebEnginePagePrivate::runUserNotificationPermissionRequest(const QUrl &securityOrigin)
+{
+ Q_Q(QWebEnginePage);
+ Q_EMIT q->featurePermissionRequested(securityOrigin, QWebEnginePage::Notifications);
+}
+
QObject *QWebEnginePagePrivate::accessibilityParentObject()
{
return view;
@@ -1874,6 +1882,7 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
d->adapter->grantMouseLockPermission(true);
break;
case Notifications:
+ d->adapter->runUserNotificationRequestCallback(securityOrigin, true);
break;
}
} else { // if (policy == PermissionDeniedByUser)
@@ -1892,6 +1901,7 @@ void QWebEnginePage::setFeaturePermission(const QUrl &securityOrigin, QWebEngine
d->adapter->grantMouseLockPermission(false);
break;
case Notifications:
+ d->adapter->runUserNotificationRequestCallback(securityOrigin, false);
break;
}
}
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 55450e438..4956877a9 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -185,9 +185,7 @@ public:
Q_ENUM(NavigationType)
enum Feature {
-#ifndef Q_QDOC
Notifications = 0,
-#endif
Geolocation = 1,
MediaAudioCapture = 2,
MediaVideoCapture,
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index bf2f43f80..d597383e2 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -132,6 +132,7 @@ public:
void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override;
void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override;
void runGeolocationPermissionRequest(const QUrl &securityOrigin) override;
+ void runUserNotificationPermissionRequest(const QUrl &securityOrigin) override;
void runMouseLockPermissionRequest(const QUrl &securityOrigin) override;
void runQuotaRequest(QWebEngineQuotaRequest) override;
void runRegisterProtocolHandlerRequest(QWebEngineRegisterProtocolHandlerRequest) override;
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index e9703ffe8..74dc14da0 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -43,6 +43,7 @@
#include "qwebenginecookiestore.h"
#include "qwebenginedownloaditem.h"
#include "qwebenginedownloaditem_p.h"
+#include "qwebenginenotificationpresenter_p.h"
#include "qwebenginepage.h"
#include "qwebenginepage_p.h"
#include "qwebenginesettings.h"
@@ -140,6 +141,12 @@ using QtWebEngineCore::ProfileAdapter;
Both session and persistent cookies are saved to and restored from disk.
*/
+void QWebEngineProfilePrivate::showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &notification)
+{
+ if (m_notificationPresenter)
+ m_notificationPresenter(QWebEngineNotification(notification));
+}
+
/*!
\fn QWebEngineProfile::downloadRequested(QWebEngineDownloadItem *download)
@@ -634,6 +641,27 @@ QWebEngineScriptCollection *QWebEngineProfile::scripts() const
}
/*!
+ Sets the function \a notificationPresenter as responsible for presenting sent notifications.
+
+ \since 5.13
+ \sa QWebEngineNotification
+*/
+void QWebEngineProfile::setNotificationPresenter(const std::function<void(const QWebEngineNotification &)> &notificationPresenter)
+{
+ Q_D(QWebEngineProfile);
+ d->m_notificationPresenter = notificationPresenter;
+}
+
+/*!
+ \overload
+*/
+void QWebEngineProfile::setNotificationPresenter(std::function<void(const QWebEngineNotification &)> &&notificationPresenter)
+{
+ Q_D(QWebEngineProfile);
+ d->m_notificationPresenter = std::move(notificationPresenter);
+}
+
+/*!
Returns the default profile.
The default profile uses the storage name "Default".
@@ -645,6 +673,8 @@ QWebEngineProfile *QWebEngineProfile::defaultProfile()
static QWebEngineProfile* profile = new QWebEngineProfile(
new QWebEngineProfilePrivate(ProfileAdapter::createDefaultProfileAdapter()),
ProfileAdapter::globalQObjectRoot());
+ if (!profile->d_ptr->m_notificationPresenter)
+ profile->setNotificationPresenter(&defaultNotificationPresenter);
return profile;
}
diff --git a/src/webenginewidgets/api/qwebengineprofile.h b/src/webenginewidgets/api/qwebengineprofile.h
index 79e83c377..5ad999c00 100644
--- a/src/webenginewidgets/api/qwebengineprofile.h
+++ b/src/webenginewidgets/api/qwebengineprofile.h
@@ -46,12 +46,15 @@
#include <QtCore/qscopedpointer.h>
#include <QtCore/qstring.h>
+#include <functional>
+
QT_BEGIN_NAMESPACE
class QObject;
class QUrl;
class QWebEngineCookieStore;
class QWebEngineDownloadItem;
+class QWebEngineNotification;
class QWebEnginePage;
class QWebEnginePagePrivate;
class QWebEngineProfilePrivate;
@@ -137,6 +140,9 @@ public:
QString downloadPath() const;
void setDownloadPath(const QString &path);
+ void setNotificationPresenter(const std::function<void(const QWebEngineNotification &)> &notificationPresenter);
+ void setNotificationPresenter(std::function<void(const QWebEngineNotification &)> &&notificationPresenter);
+
static QWebEngineProfile *defaultProfile();
Q_SIGNALS:
diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h
index 9ff8df849..3dd024ffd 100644
--- a/src/webenginewidgets/api/qwebengineprofile_p.h
+++ b/src/webenginewidgets/api/qwebengineprofile_p.h
@@ -60,6 +60,8 @@
#include <QScopedPointer>
#include <QSharedPointer>
+#include <functional>
+
namespace QtWebEngineCore {
class ProfileAdapter;
}
@@ -68,6 +70,7 @@ QT_BEGIN_NAMESPACE
class QWebEngineBrowserContext;
class QWebEngineProfilePrivate;
+class QWebEngineNotification;
class QWebEngineSettings;
class QWebEngineProfilePrivate : public QtWebEngineCore::ProfileAdapterClient {
@@ -84,12 +87,15 @@ public:
void downloadRequested(DownloadItemInfo &info) override;
void downloadUpdated(const DownloadItemInfo &info) override;
+ void showNotification(QSharedPointer<QtWebEngineCore::UserNotificationController> &) override;
+
private:
QWebEngineProfile *q_ptr;
QWebEngineSettings *m_settings;
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
QScopedPointer<QWebEngineScriptCollection> m_scriptCollection;
QMap<quint32, QPointer<QWebEngineDownloadItem> > m_ongoingDownloads;
+ std::function<void(const QWebEngineNotification &)> m_notificationPresenter;
};
QT_END_NAMESPACE
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index d012c678c..427668a11 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -285,6 +285,8 @@
This enum describes the platform feature access categories that the user may be asked to grant
or deny access to:
+ \value Notifications
+ Web notifications for the end-user.
\value Geolocation
Location hardware or service.
\value MediaAudioCapture
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index 4669c2bce..d4fb40dc7 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -19,6 +19,7 @@ SOURCES = \
api/qwebenginedownloaditem.cpp \
api/qwebenginefullscreenrequest.cpp \
api/qwebenginehistory.cpp \
+ api/qwebenginenotificationpresenter.cpp \
api/qwebenginepage.cpp \
api/qwebengineprofile.cpp \
api/qwebenginescript.cpp \
@@ -36,6 +37,7 @@ HEADERS = \
api/qwebenginedownloaditem_p.h \
api/qwebenginefullscreenrequest.h \
api/qwebenginehistory.h \
+ api/qwebenginenotificationpresenter_p.h \
api/qwebenginepage.h \
api/qwebenginepage_p.h \
api/qwebengineprofile.h \