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 43namespace WebCore { 44 45PassRef<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 52NotificationCenter::NotificationCenter(ScriptExecutionContext* context, NotificationClient* client) 53 : ActiveDOMObject(context) 54 , m_client(client) 55{ 56} 57 58#if ENABLE(LEGACY_NOTIFICATIONS) 59int 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) 79void 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 99void 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 108void NotificationCenter::requestTimedOut(NotificationCenter::NotificationRequestCallback* request) 109{ 110 m_callbacks.remove(request); 111} 112 113PassRefPtr<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 120NotificationCenter::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 127void NotificationCenter::NotificationRequestCallback::startTimer() 128{ 129 m_timer.startOneShot(0); 130} 131 132void NotificationCenter::NotificationRequestCallback::timerFired(Timer<NotificationCenter::NotificationRequestCallback>&) 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) 142