[WK2] Notifications clobber each other with multiple processes
[WebKit-https.git] / Source / WebKit2 / WebProcess / Notifications / NotificationPermissionRequestManager.cpp
1 /*
2  * Copyright (C) 2011, 2012 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 "NotificationPermissionRequestManager.h"
28
29 #include "WebCoreArgumentCoders.h"
30 #include "WebPage.h"
31 #include "WebPageProxyMessages.h"
32 #include "WebProcess.h"
33 #include <WebCore/Notification.h>
34 #include <WebCore/Page.h>
35 #include <WebCore/ScriptExecutionContext.h>
36 #include <WebCore/SecurityOrigin.h>
37 #include <WebCore/Settings.h>
38
39 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
40 #include "WebNotificationManager.h"
41 #endif
42
43 using namespace WebCore;
44
45 namespace WebKit {
46
47 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
48 static uint64_t generateRequestID()
49 {
50     static uint64_t uniqueRequestID = 1;
51     return uniqueRequestID++;
52 }
53 #endif
54
55 PassRefPtr<NotificationPermissionRequestManager> NotificationPermissionRequestManager::create(WebPage* page)
56 {
57     return adoptRef(new NotificationPermissionRequestManager(page));
58 }
59
60 NotificationPermissionRequestManager::NotificationPermissionRequestManager(WebPage* page)
61 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
62     : m_page(page)
63 #endif
64 {
65     (void)page;
66 }
67
68 #if ENABLE(NOTIFICATIONS)
69 void NotificationPermissionRequestManager::startRequest(SecurityOrigin* origin, PassRefPtr<NotificationPermissionCallback> callback)
70 {
71     NotificationClient::Permission permission = permissionLevel(origin);
72     if (permission != NotificationClient::PermissionNotAllowed) {
73         callback->handleEvent(Notification::permissionString(permission));
74         return;
75     }
76
77     uint64_t requestID = generateRequestID();
78     m_originToIDMap.set(origin, requestID);
79     m_idToOriginMap.set(requestID, origin);
80     m_idToCallbackMap.set(requestID, callback);
81     m_page->send(Messages::WebPageProxy::RequestNotificationPermission(requestID, origin->toString()));
82 }
83 #endif
84
85 #if ENABLE(LEGACY_NOTIFICATIONS)
86 void NotificationPermissionRequestManager::startRequest(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback)
87 {
88     NotificationClient::Permission permission = permissionLevel(origin);
89     if (permission != NotificationClient::PermissionNotAllowed) {
90         if (callback)
91             callback->handleEvent();
92         return;
93     }
94     
95     uint64_t requestID = generateRequestID();
96     m_originToIDMap.set(origin, requestID);
97     m_idToOriginMap.set(requestID, origin);
98     m_idToVoidCallbackMap.set(requestID, callback);
99     m_page->send(Messages::WebPageProxy::RequestNotificationPermission(requestID, origin->toString()));
100 }
101 #endif
102
103 void NotificationPermissionRequestManager::cancelRequest(SecurityOrigin* origin)
104 {
105 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
106     uint64_t id = m_originToIDMap.take(origin);
107     if (!id)
108         return;
109     
110     m_idToOriginMap.remove(id);
111 #if ENABLE(NOTIFICATIONS)
112     m_idToCallbackMap.remove(id);
113 #endif
114 #if ENABLE(LEGACY_NOTIFICATIONS)
115     m_idToVoidCallbackMap.remove(id);
116 #endif
117 #else
118     UNUSED_PARAM(origin);
119 #endif
120 }
121
122 NotificationClient::Permission NotificationPermissionRequestManager::permissionLevel(SecurityOrigin* securityOrigin)
123 {
124 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
125     if (!m_page->corePage()->settings()->notificationsEnabled())
126         return NotificationClient::PermissionDenied;
127     
128     return WebProcess::shared().supplement<WebNotificationManager>()->policyForOrigin(securityOrigin);
129 #else
130     UNUSED_PARAM(securityOrigin);
131     return NotificationClient::PermissionDenied;
132 #endif
133 }
134
135 void NotificationPermissionRequestManager::setPermissionLevelForTesting(const String& originString, bool allowed)
136 {
137 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
138     WebProcess::shared().supplement<WebNotificationManager>()->didUpdateNotificationDecision(originString, allowed);
139 #else
140     UNUSED_PARAM(originString);
141     UNUSED_PARAM(allowed);
142 #endif
143 }
144
145 void NotificationPermissionRequestManager::removeAllPermissionsForTesting()
146 {
147 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
148     WebProcess::shared().supplement<WebNotificationManager>()->removeAllPermissionsForTesting();
149 #endif
150 }
151
152 void NotificationPermissionRequestManager::didReceiveNotificationPermissionDecision(uint64_t requestID, bool allowed)
153 {
154 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
155     if (!isRequestIDValid(requestID))
156         return;
157
158     RefPtr<WebCore::SecurityOrigin> origin = m_idToOriginMap.take(requestID);
159     m_originToIDMap.remove(origin);
160
161     WebProcess::shared().supplement<WebNotificationManager>()->didUpdateNotificationDecision(origin->toString(), allowed);
162
163 #if ENABLE(LEGACY_NOTIFICATIONS)
164     RefPtr<VoidCallback> voidCallback = m_idToVoidCallbackMap.take(requestID);
165     if (voidCallback) {
166         voidCallback->handleEvent();
167         return;
168     }
169 #endif
170
171 #if ENABLE(NOTIFICATIONS)
172     RefPtr<NotificationPermissionCallback> callback = m_idToCallbackMap.take(requestID);
173     if (!callback)
174         return;
175     
176     callback->handleEvent(Notification::permissionString(allowed ? NotificationClient::PermissionAllowed : NotificationClient::PermissionDenied));
177 #endif
178
179 #else
180     UNUSED_PARAM(requestID);
181     UNUSED_PARAM(allowed);
182 #endif    
183 }
184
185 } // namespace WebKit