NotificationManager.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
  3. * Copyright (C) 2012 Research In Motion Limited. 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
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  15. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  16. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  17. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  18. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  19. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  20. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  21. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  22. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  23. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  24. * THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "config.h"
  27. #include "NotificationManager.h"
  28. #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
  29. #include "UUID.h"
  30. #include "UserGestureIndicator.h"
  31. #include "WebPage_p.h"
  32. #include <BlackBerryPlatformString.h>
  33. #include <vector>
  34. using namespace WebCore;
  35. namespace BlackBerry {
  36. namespace WebKit {
  37. NotificationManager::NotificationManager(WebPagePrivate* webPagePrivate)
  38. : m_webPagePrivate(webPagePrivate)
  39. {
  40. }
  41. NotificationManager::~NotificationManager()
  42. {
  43. }
  44. bool NotificationManager::show(Notification* notification)
  45. {
  46. String notificationID = createCanonicalUUIDString();
  47. m_notificationMap.set(notification, notificationID);
  48. m_notificationIDMap.set(notificationID, notification);
  49. NotificationContextMap::iterator it = m_notificationContextMap.add(notification->scriptExecutionContext(), Vector<String>()).iterator;
  50. it->value.append(notificationID);
  51. m_webPagePrivate->client()->showNotification(notificationID, notification->title(), notification->body(), notification->iconURL().string(), notification->tag(), notification->scriptExecutionContext()->securityOrigin()->toString());
  52. return true;
  53. }
  54. void NotificationManager::cancel(Notification* notification)
  55. {
  56. String notificationID = m_notificationMap.get(notification);
  57. if (!notificationID)
  58. return;
  59. m_webPagePrivate->client()->cancelNotification(notificationID);
  60. }
  61. void NotificationManager::clearNotifications(ScriptExecutionContext* context)
  62. {
  63. NotificationContextMap::iterator it = m_notificationContextMap.find(context);
  64. if (it == m_notificationContextMap.end())
  65. return;
  66. Vector<String>& notificationIDs = it->value;
  67. std::vector<BlackBerry::Platform::String> ids;
  68. size_t count = notificationIDs.size();
  69. for (size_t i = 0; i < count; ++i) {
  70. ids.push_back(notificationIDs[i]);
  71. RefPtr<Notification> notification = m_notificationIDMap.take(notificationIDs[i]);
  72. if (!notification)
  73. continue;
  74. notification->finalize();
  75. m_notificationMap.remove(notification);
  76. }
  77. m_webPagePrivate->client()->clearNotifications(ids);
  78. m_notificationContextMap.remove(it);
  79. }
  80. void NotificationManager::notificationObjectDestroyed(Notification* notification)
  81. {
  82. String notificationID = m_notificationMap.take(notification);
  83. if (!notificationID)
  84. return;
  85. m_notificationIDMap.remove(notificationID);
  86. removeNotificationFromContextMap(notificationID, notification);
  87. m_webPagePrivate->client()->notificationDestroyed(notificationID);
  88. }
  89. #if ENABLE(LEGACY_NOTIFICATIONS)
  90. void NotificationManager::requestPermission(ScriptExecutionContext* context, PassRefPtr<VoidCallback> callback)
  91. {
  92. SecurityOrigin* origin = context->securityOrigin();
  93. String requestID = createCanonicalUUIDString();
  94. m_originToIDMap.set(origin, requestID);
  95. m_idToOriginMap.set(requestID, origin);
  96. m_idToVoidCallbackMap.set(requestID, callback);
  97. m_webPagePrivate->client()->requestNotificationPermission(requestID, origin->toString());
  98. }
  99. #endif
  100. #if ENABLE(NOTIFICATIONS)
  101. void NotificationManager::requestPermission(ScriptExecutionContext* context, PassRefPtr<NotificationPermissionCallback> callback)
  102. {
  103. SecurityOrigin* origin = context->securityOrigin();
  104. String requestID = createCanonicalUUIDString();
  105. m_originToIDMap.set(origin, requestID);
  106. m_idToOriginMap.set(requestID, origin);
  107. m_idToCallbackMap.set(requestID, callback);
  108. m_webPagePrivate->client()->requestNotificationPermission(requestID, origin->toString());
  109. }
  110. #endif
  111. void NotificationManager::cancelRequestsForPermission(ScriptExecutionContext* context)
  112. {
  113. SecurityOrigin* origin = context->securityOrigin();
  114. String requestID = m_originToIDMap.take(origin);
  115. if (!requestID)
  116. return;
  117. m_idToOriginMap.remove(requestID);
  118. #if ENABLE(LEGACY_NOTIFICATIONS)
  119. m_idToVoidCallbackMap.remove(requestID);
  120. #endif
  121. #if ENABLE(NOTIFICATIONS)
  122. m_idToCallbackMap.remove(requestID);
  123. #endif
  124. }
  125. NotificationClient::Permission NotificationManager::checkPermission(ScriptExecutionContext* context)
  126. {
  127. return static_cast<NotificationClient::Permission>(m_webPagePrivate->client()->checkNotificationPermission(context->securityOrigin()->toString()));
  128. }
  129. void NotificationManager::updatePermission(const String& requestID, bool allowed)
  130. {
  131. RefPtr<WebCore::SecurityOrigin> origin = m_idToOriginMap.take(requestID);
  132. m_originToIDMap.remove(origin);
  133. #if ENABLE(LEGACY_NOTIFICATIONS)
  134. RefPtr<VoidCallback> voidCallback = m_idToVoidCallbackMap.take(requestID);
  135. if (voidCallback) {
  136. voidCallback->handleEvent();
  137. return;
  138. }
  139. #endif
  140. #if ENABLE(NOTIFICATIONS)
  141. RefPtr<NotificationPermissionCallback> callback = m_idToCallbackMap.take(requestID);
  142. if (!callback)
  143. return;
  144. callback->handleEvent(Notification::permissionString(allowed ? NotificationClient::PermissionAllowed : NotificationClient::PermissionDenied));
  145. #endif
  146. }
  147. void NotificationManager::notificationClicked(const String& notificationID)
  148. {
  149. RefPtr<Notification> notification = m_notificationIDMap.get(notificationID);
  150. if (!notification)
  151. return;
  152. // Indicate that this event is being dispatched in reaction to a user's interaction with a platform notification.
  153. UserGestureIndicator indicator(DefinitelyProcessingNewUserGesture);
  154. notification->dispatchClickEvent();
  155. }
  156. void NotificationManager::notificationClosed(const String& notificationID)
  157. {
  158. RefPtr<Notification> notification = m_notificationIDMap.take(notificationID);
  159. if (!notification)
  160. return;
  161. m_notificationMap.remove(notification);
  162. removeNotificationFromContextMap(notificationID, notification.get());
  163. notification->dispatchCloseEvent();
  164. }
  165. void NotificationManager::notificationError(const String& notificationID)
  166. {
  167. RefPtr<Notification> notification = m_notificationIDMap.take(notificationID);
  168. if (!notification)
  169. return;
  170. notification->dispatchErrorEvent();
  171. }
  172. void NotificationManager::notificationShown(const String& notificationID)
  173. {
  174. RefPtr<Notification> notification = m_notificationIDMap.get(notificationID);
  175. if (!notification)
  176. return;
  177. notification->dispatchShowEvent();
  178. }
  179. void NotificationManager::removeNotificationFromContextMap(const String& notificationID, Notification* notification)
  180. {
  181. // This is a helper function for managing the hash maps.
  182. NotificationContextMap::iterator it = m_notificationContextMap.find(notification->scriptExecutionContext());
  183. ASSERT(it != m_notificationContextMap.end());
  184. size_t index = it->value.find(notificationID);
  185. ASSERT(index != notFound);
  186. it->value.remove(index);
  187. if (it->value.isEmpty())
  188. m_notificationContextMap.remove(it);
  189. }
  190. }
  191. }
  192. #endif // ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)