[WK2] Sync call for notifications permissions causes flashes on gmail.com
[WebKit-https.git] / Source / WebKit2 / WebProcess / Notifications / WebNotificationManager.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebNotificationManager.h"
28
29 #include "WebPage.h"
30 #include "WebProcess.h"
31
32 #if ENABLE(NOTIFICATIONS)
33 #include "WebNotification.h"
34 #include "WebNotificationManagerProxyMessages.h"
35 #include "WebPageProxyMessages.h"
36 #include <WebCore/Notification.h>
37 #include <WebCore/Page.h>
38 #include <WebCore/ScriptExecutionContext.h>
39 #include <WebCore/SecurityOrigin.h>
40 #include <WebCore/Settings.h>
41 #endif
42
43 using namespace WebCore;
44
45 namespace WebKit {
46
47 #if ENABLE(NOTIFICATIONS)
48 static uint64_t generateNotificationID()
49 {
50     static uint64_t uniqueNotificationID = 1;
51     return uniqueNotificationID++;
52 }
53 #endif
54
55 WebNotificationManager::WebNotificationManager(WebProcess* process)
56     : m_process(process)
57 {
58 }
59
60 WebNotificationManager::~WebNotificationManager()
61 {
62 }
63
64 void WebNotificationManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
65 {
66     didReceiveWebNotificationManagerMessage(connection, messageID, arguments);
67 }
68
69 void WebNotificationManager::initialize(const HashMap<String, bool>& permissions)
70 {
71     m_permissionsMap = permissions;
72 }
73
74 void WebNotificationManager::didUpdateNotificationDecision(const String& originString, bool allowed)
75 {
76     m_permissionsMap.set(originString, allowed);
77 }
78
79 void WebNotificationManager::didRemoveNotificationDecisions(const Vector<String>& originStrings)
80 {
81     size_t count = originStrings.size();
82     for (size_t i = 0; i < count; ++i)
83         m_permissionsMap.remove(originStrings[i]);
84 }
85
86 NotificationPresenter::Permission WebNotificationManager::policyForOrigin(WebCore::SecurityOrigin *origin) const
87 {
88     if (!origin)
89         return NotificationPresenter::PermissionNotAllowed;
90     
91     HashMap<String, bool>::const_iterator it = m_permissionsMap.find(origin->toString());
92     if (it != m_permissionsMap.end())
93         return it->second ? NotificationPresenter::PermissionAllowed : NotificationPresenter::PermissionDenied;
94     
95     return NotificationPresenter::PermissionNotAllowed;
96 }
97
98 bool WebNotificationManager::show(Notification* notification, WebPage* page)
99 {
100 #if ENABLE(NOTIFICATIONS)
101     if (!notification || !page->corePage()->settings()->notificationsEnabled())
102         return true;
103     
104     uint64_t notificationID = generateNotificationID();
105     m_notificationMap.set(notification, notificationID);
106     m_notificationIDMap.set(notificationID, notification);
107     
108     m_process->connection()->send(Messages::WebPageProxy::ShowNotification(notification->contents().title, notification->contents().body, notification->scriptExecutionContext()->securityOrigin()->toString(), notificationID), page->pageID());
109 #endif
110     return true;
111 }
112
113 void WebNotificationManager::cancel(Notification* notification, WebPage* page)
114 {
115 #if ENABLE(NOTIFICATIONS)
116     if (!notification || !page->corePage()->settings()->notificationsEnabled())
117         return;
118     
119     uint64_t notificationID = m_notificationMap.get(notification);
120     if (!notificationID)
121         return;
122     
123     m_process->connection()->send(Messages::WebNotificationManagerProxy::Cancel(notificationID), page->pageID());
124 #endif
125 }
126
127 void WebNotificationManager::didDestroyNotification(Notification* notification, WebPage* page)
128 {
129 #if ENABLE(NOTIFICATIONS)
130     uint64_t notificationID = m_notificationMap.take(notification);
131     if (!notificationID)
132         return;
133
134     m_notificationIDMap.take(notificationID);
135     m_process->connection()->send(Messages::WebNotificationManagerProxy::DidDestroyNotification(notificationID), page->pageID());
136 #endif
137 }
138
139 void WebNotificationManager::didShowNotification(uint64_t notificationID)
140 {
141 #if ENABLE(NOTIFICATIONS)
142     if (!isNotificationIDValid(notificationID))
143         return;
144     
145     RefPtr<Notification> notification = m_notificationIDMap.get(notificationID);
146     if (!notification)
147         return;
148
149     notification->dispatchShowEvent();
150 #endif
151 }
152
153 void WebNotificationManager::didClickNotification(uint64_t notificationID)
154 {
155 #if ENABLE(NOTIFICATIONS)
156     if (!isNotificationIDValid(notificationID))
157         return;
158
159     RefPtr<Notification> notification = m_notificationIDMap.get(notificationID);
160     if (!notification)
161         return;
162
163     notification->dispatchClickEvent();
164 #endif
165 }
166
167 void WebNotificationManager::didCloseNotifications(const Vector<uint64_t>& notificationIDs)
168 {
169 #if ENABLE(NOTIFICATIONS)
170     size_t count = notificationIDs.size();
171     for (size_t i = 0; i < count; ++i) {
172         uint64_t notificationID = notificationIDs[i];
173         if (!isNotificationIDValid(notificationID))
174             continue;
175
176         RefPtr<Notification> notification = m_notificationIDMap.get(notificationID);
177         if (!notification)
178             continue;
179
180         notification->dispatchCloseEvent();
181     }
182 #endif
183 }
184
185 } // namespace WebKit