bafb5ca3597d3a50a3bc0273170a9fe25d378d3f
[WebKit-https.git] / Source / WebCore / Modules / notifications / NotificationCenter.cpp
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  * Copyright (C) 2012 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "config.h"
33
34 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
35
36 #include "NotificationCenter.h"
37
38 #include "Document.h"
39 #include "NotificationClient.h"
40 #include "SecurityOrigin.h"
41 #include "WorkerGlobalScope.h"
42
43 namespace WebCore {
44
45 PassRef<NotificationCenter> NotificationCenter::create(ScriptExecutionContext* context, NotificationClient* client)
46 {
47     auto notificationCenter = adoptRef(*new NotificationCenter(context, client));
48     notificationCenter.get().suspendIfNeeded();
49     return notificationCenter;
50 }
51
52 NotificationCenter::NotificationCenter(ScriptExecutionContext* context, NotificationClient* client)
53     : ActiveDOMObject(context)
54     , m_client(client)
55 {
56 }
57
58 #if ENABLE(LEGACY_NOTIFICATIONS)
59 int NotificationCenter::checkPermission()
60 {
61     if (!client() || !scriptExecutionContext())
62         return NotificationClient::PermissionDenied;
63
64     switch (scriptExecutionContext()->securityOrigin()->canShowNotifications()) {
65     case SecurityOrigin::AlwaysAllow:
66         return NotificationClient::PermissionAllowed;
67     case SecurityOrigin::AlwaysDeny:
68         return NotificationClient::PermissionDenied;
69     case SecurityOrigin::Ask:
70         return m_client->checkPermission(scriptExecutionContext());
71     }
72
73     ASSERT_NOT_REACHED();
74     return m_client->checkPermission(scriptExecutionContext());
75 }
76 #endif
77
78 #if ENABLE(LEGACY_NOTIFICATIONS)
79 void NotificationCenter::requestPermission(PassRefPtr<VoidCallback> callback)
80 {
81     if (!client() || !scriptExecutionContext())
82         return;
83
84     switch (scriptExecutionContext()->securityOrigin()->canShowNotifications()) {
85     case SecurityOrigin::AlwaysAllow:
86     case SecurityOrigin::AlwaysDeny: {
87         m_callbacks.add(NotificationRequestCallback::createAndStartTimer(this, callback));
88         return;
89     }
90     case SecurityOrigin::Ask:
91         return m_client->requestPermission(scriptExecutionContext(), callback);
92     }
93
94     ASSERT_NOT_REACHED();
95     m_client->requestPermission(scriptExecutionContext(), callback);
96 }
97 #endif
98
99 void NotificationCenter::stop()
100 {
101     if (!m_client)
102         return;
103     m_client->cancelRequestsForPermission(scriptExecutionContext());
104     m_client->clearNotifications(scriptExecutionContext());
105     m_client = 0;
106 }
107
108 void NotificationCenter::requestTimedOut(NotificationCenter::NotificationRequestCallback* request)
109 {
110     m_callbacks.remove(request);
111 }
112
113 PassRefPtr<NotificationCenter::NotificationRequestCallback> NotificationCenter::NotificationRequestCallback::createAndStartTimer(NotificationCenter* center, PassRefPtr<VoidCallback> callback)
114 {
115     RefPtr<NotificationCenter::NotificationRequestCallback> requestCallback = adoptRef(new NotificationCenter::NotificationRequestCallback(center, callback));
116     requestCallback->startTimer();
117     return requestCallback.release();
118 }
119
120 NotificationCenter::NotificationRequestCallback::NotificationRequestCallback(NotificationCenter* center, PassRefPtr<VoidCallback> callback)
121     : m_notificationCenter(center)
122     , m_timer(this, &NotificationCenter::NotificationRequestCallback::timerFired)
123     , m_callback(callback)
124 {
125 }
126
127 void NotificationCenter::NotificationRequestCallback::startTimer()
128 {
129     m_timer.startOneShot(0);
130 }
131
132 void NotificationCenter::NotificationRequestCallback::timerFired(Timer&)
133 {
134     if (m_callback)
135         m_callback->handleEvent();
136     m_notificationCenter->requestTimedOut(this);
137 }
138
139 } // namespace WebCore
140
141 #endif // ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)