16c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen/*
26c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * Copyright (C) 2010 Google Inc. All rights reserved.
36c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen *
46c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * Redistribution and use in source and binary forms, with or without
56c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * modification, are permitted provided that the following conditions are
66c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * met:
76c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen *
86c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen *     * Redistributions of source code must retain the above copyright
96c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * notice, this list of conditions and the following disclaimer.
106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen *     * Redistributions in binary form must reproduce the above
116c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * copyright notice, this list of conditions and the following disclaimer
126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * in the documentation and/or other materials provided with the
136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * distribution.
146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen *     * Neither the name of Google Inc. nor the names of its
156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * contributors may be used to endorse or promote products derived from
166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * this software without specific prior written permission.
176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen *
186c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
196c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
206c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
226c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
236c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
256c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
276c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen */
306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include "config.h"
326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include "NotificationPresenter.h"
336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
34a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebKit.h"
35a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebKitClient.h"
36a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebNotification.h"
37a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebNotificationPermissionCallback.h"
38a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebSecurityOrigin.h"
39a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebString.h"
40a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WebURL.h"
416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#include "googleurl/src/gurl.h"
425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include <wtf/text/CString.h>
435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include <wtf/text/WTFString.h>
446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenusing namespace WebKit;
466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenstatic WebString identifierForNotification(const WebNotification& notification)
485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (notification.isHTML())
505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return notification.url().spec().utf16();
515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return notification.title();
525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
545abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrickstatic void deferredDisplayDispatch(void* context)
555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
565abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    WebNotification* notification = static_cast<WebNotification*>(context);
575abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    notification->dispatchDisplayEvent();
585abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    delete notification;
595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
605ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
616c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid NotificationPresenter::grantPermission(const WebString& origin)
626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // Make sure it's in the form of an origin.
646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    GURL url(origin);
65f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    m_allowedOrigins.add(WTF::String(url.GetOrigin().spec().c_str()));
666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
685ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenbool NotificationPresenter::simulateClick(const WebString& title)
695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
705ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    WTF::String id(title.data(), title.length());
715ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (m_activeNotifications.find(id) == m_activeNotifications.end())
725ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return false;
735ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
745ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    const WebNotification& notification = m_activeNotifications.find(id)->second;
755ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    WebNotification eventTarget(notification);
765ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    eventTarget.dispatchClickEvent();
775ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return true;
785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen// The output from all these methods matches what DumpRenderTree produces.
816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenbool NotificationPresenter::show(const WebNotification& notification)
826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    WebString identifier = identifierForNotification(notification);
845af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    if (!notification.replaceId().isEmpty()) {
85f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        WTF::String replaceId(notification.replaceId().data(), notification.replaceId().length());
865af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        if (m_replacements.find(replaceId) != m_replacements.end())
875af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke            printf("REPLACING NOTIFICATION %s\n",
885af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke                   m_replacements.find(replaceId)->second.utf8().data());
895af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
90f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        m_replacements.set(replaceId, WTF::String(identifier.data(), identifier.length()));
915af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    }
925af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (notification.isHTML()) {
946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        printf("DESKTOP NOTIFICATION: contents at %s\n",
956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen               notification.url().spec().data());
966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    } else {
975af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke        printf("DESKTOP NOTIFICATION:%s icon %s, title %s, text %s\n",
982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block               notification.direction() == WebTextDirectionRightToLeft ? "(RTL)" : "",
996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen               notification.iconURL().isEmpty() ? "" :
1006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen               notification.iconURL().spec().data(),
1016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen               notification.title().isEmpty() ? "" :
1026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen               notification.title().utf8().data(),
1036c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen               notification.body().isEmpty() ? "" :
1046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen               notification.body().utf8().data());
1056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
1066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    WTF::String id(identifier.data(), identifier.length());
1085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_activeNotifications.set(id, notification);
1095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1105abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    webKitClient()->callOnMainThread(deferredDisplayDispatch, new WebNotification(notification));
1116c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return true;
1126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
1136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid NotificationPresenter::cancel(const WebNotification& notification)
1156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
1165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    WebString identifier = identifierForNotification(notification);
1176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    printf("DESKTOP NOTIFICATION CLOSED: %s\n", identifier.utf8().data());
1186c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    WebNotification eventTarget(notification);
1196c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    eventTarget.dispatchCloseEvent(false);
1205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    WTF::String id(identifier.data(), identifier.length());
1225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_activeNotifications.remove(id);
1236c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
1246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1256c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid NotificationPresenter::objectDestroyed(const WebKit::WebNotification& notification)
1266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
1275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    WebString identifier = identifierForNotification(notification);
1285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    WTF::String id(identifier.data(), identifier.length());
1295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_activeNotifications.remove(id);
1306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
1316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian MonsenWebNotificationPresenter::Permission NotificationPresenter::checkPermission(const WebURL& url)
1336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
1346c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    // Check with the layout test controller
135f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    WTF::String origin = WTF::String(static_cast<GURL>(url).GetOrigin().spec().c_str());
1366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    bool allowed = m_allowedOrigins.find(origin) != m_allowedOrigins.end();
1376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    return allowed ? WebNotificationPresenter::PermissionAllowed
1386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        : WebNotificationPresenter::PermissionDenied;
1396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
1406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
1416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid NotificationPresenter::requestPermission(
1426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    const WebSecurityOrigin& origin,
1436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    WebNotificationPermissionCallback* callback)
1446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
1456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    printf("DESKTOP NOTIFICATION PERMISSION REQUESTED: %s\n",
1466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen           origin.toString().utf8().data());
1476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    callback->permissionRequestComplete();
1486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
149