summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp')
-rw-r--r--Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp
new file mode 100644
index 000000000..b60669adb
--- /dev/null
+++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNotificationProvider.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ * Copyright (C) 2014 Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebKitNotificationProvider.h"
+
+#include "APIArray.h"
+#include "APIDictionary.h"
+#include "WKNotificationManager.h"
+#include "WebKitNotificationPrivate.h"
+#include "WebKitWebContextPrivate.h"
+#include "WebKitWebViewPrivate.h"
+#include "WebNotificationManagerProxy.h"
+#include "WebPageProxy.h"
+#include <wtf/text/CString.h>
+
+using namespace WebKit;
+
+static inline WebKitNotificationProvider* toNotificationProvider(const void* clientInfo)
+{
+ return static_cast<WebKitNotificationProvider*>(const_cast<void*>(clientInfo));
+}
+
+static void showCallback(WKPageRef page, WKNotificationRef notification, const void* clientInfo)
+{
+ toNotificationProvider(clientInfo)->show(toImpl(page), *toImpl(notification));
+}
+
+static void cancelCallback(WKNotificationRef notification, const void* clientInfo)
+{
+ toNotificationProvider(clientInfo)->cancel(*toImpl(notification));
+}
+
+static WKDictionaryRef notificationPermissionsCallback(const void* clientInfo)
+{
+ return toAPI(toNotificationProvider(clientInfo)->notificationPermissions().leakRef());
+}
+
+static void clearNotificationsCallback(WKArrayRef notificationIDs, const void* clientInfo)
+{
+ toNotificationProvider(clientInfo)->clearNotifications(toImpl(notificationIDs));
+}
+
+WebKitNotificationProvider::~WebKitNotificationProvider()
+{
+}
+
+Ref<WebKitNotificationProvider> WebKitNotificationProvider::create(WebNotificationManagerProxy* notificationManager, WebKitWebContext* webContext)
+{
+ return adoptRef(*new WebKitNotificationProvider(notificationManager, webContext));
+}
+
+WebKitNotificationProvider::WebKitNotificationProvider(WebNotificationManagerProxy* notificationManager, WebKitWebContext* webContext)
+ : m_webContext(webContext)
+ , m_notificationManager(notificationManager)
+{
+ ASSERT(notificationManager);
+
+ WKNotificationProviderV0 wkNotificationProvider = {
+ {
+ 0, // version
+ this, // clientInfo
+ },
+ showCallback,
+ cancelCallback,
+ 0, // didDestroyNotificationCallback,
+ 0, // addNotificationManagerCallback,
+ 0, // removeNotificationManagerCallback,
+ notificationPermissionsCallback,
+ clearNotificationsCallback,
+ };
+
+ WKNotificationManagerSetProvider(toAPI(notificationManager), reinterpret_cast<WKNotificationProviderBase*>(&wkNotificationProvider));
+}
+
+void WebKitNotificationProvider::notificationCloseCallback(WebKitNotification* notification, WebKitNotificationProvider* provider)
+{
+ uint64_t notificationID = webkit_notification_get_id(notification);
+ Vector<RefPtr<API::Object>> arrayIDs;
+ arrayIDs.append(API::UInt64::create(notificationID));
+ provider->m_notificationManager->providerDidCloseNotifications(API::Array::create(WTFMove(arrayIDs)).ptr());
+ provider->m_notifications.remove(notificationID);
+}
+
+void WebKitNotificationProvider::notificationClickedCallback(WebKitNotification* notification, WebKitNotificationProvider* provider)
+{
+ provider->m_notificationManager->providerDidClickNotification(webkit_notification_get_id(notification));
+}
+
+void WebKitNotificationProvider::withdrawAnyPreviousNotificationMatchingTag(const CString& tag)
+{
+ if (!tag.length())
+ return;
+
+ for (auto& notification : m_notifications.values()) {
+ if (tag == webkit_notification_get_tag(notification.get())) {
+ webkit_notification_close(notification.get());
+ break;
+ }
+ }
+
+#ifndef NDEBUG
+ for (auto& notification : m_notifications.values())
+ ASSERT(tag != webkit_notification_get_tag(notification.get()));
+#endif
+}
+
+void WebKitNotificationProvider::show(WebPageProxy* page, const WebNotification& webNotification)
+{
+ GRefPtr<WebKitNotification> notification = m_notifications.get(webNotification.notificationID());
+
+ if (!notification) {
+ withdrawAnyPreviousNotificationMatchingTag(webNotification.tag().utf8());
+ notification = adoptGRef(webkitNotificationCreate(WEBKIT_WEB_VIEW(page->viewWidget()), webNotification));
+ g_signal_connect(notification.get(), "closed", G_CALLBACK(notificationCloseCallback), this);
+ g_signal_connect(notification.get(), "clicked", G_CALLBACK(notificationClickedCallback), this);
+ m_notifications.set(webNotification.notificationID(), notification);
+ }
+
+ if (webkitWebViewEmitShowNotification(WEBKIT_WEB_VIEW(page->viewWidget()), notification.get()))
+ m_notificationManager->providerDidShowNotification(webNotification.notificationID());
+}
+
+void WebKitNotificationProvider::cancelNotificationByID(uint64_t notificationID)
+{
+ if (GRefPtr<WebKitNotification> notification = m_notifications.get(notificationID))
+ webkit_notification_close(notification.get());
+}
+
+void WebKitNotificationProvider::cancel(const WebNotification& webNotification)
+{
+ cancelNotificationByID(webNotification.notificationID());
+}
+
+void WebKitNotificationProvider::clearNotifications(const API::Array* notificationIDs)
+{
+ for (const auto& item : notificationIDs->elementsOfType<API::UInt64>())
+ cancelNotificationByID(item->value());
+}
+
+RefPtr<API::Dictionary> WebKitNotificationProvider::notificationPermissions()
+{
+ webkitWebContextInitializeNotificationPermissions(m_webContext);
+ return m_notificationPermissions;
+}
+
+void WebKitNotificationProvider::setNotificationPermissions(HashMap<String, RefPtr<API::Object>>&& permissionsMap)
+{
+ m_notificationPermissions = API::Dictionary::create(WTFMove(permissionsMap));
+}