Chromium Code Reviews| Index: content/browser/notifications/notification_event_dispatcher_impl.cc |
| diff --git a/content/browser/notifications/notification_event_dispatcher_impl.cc b/content/browser/notifications/notification_event_dispatcher_impl.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d932d4c348ddf04c3f368bb6e890fb850fd7b708 |
| --- /dev/null |
| +++ b/content/browser/notifications/notification_event_dispatcher_impl.cc |
| @@ -0,0 +1,170 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/browser/notifications/notification_event_dispatcher_impl.h" |
| + |
| +#include "base/callback.h" |
| +#include "content/browser/service_worker/service_worker_context_wrapper.h" |
| +#include "content/browser/service_worker/service_worker_registration.h" |
| +#include "content/browser/service_worker/service_worker_storage.h" |
| +#include "content/public/browser/browser_context.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/storage_partition.h" |
| +#include "content/public/common/show_desktop_notification_params.h" |
| + |
| +namespace content { |
| +namespace { |
| + |
| +using NotificationClickDispatchCompleteCallback = |
| + NotificationEventDispatcher::NotificationClickDispatchCompleteCallback; |
| + |
| +// To be called when the notificationclick event has finished executing. Will |
| +// post a task to call |done_callback| on the UI thread. |
|
Michael van Ouwerkerk
2014/12/08 15:13:42
s/|done_callback|/|callback|/
Peter Beverloo
2014/12/08 17:27:08
Done.
|
| +void NotificationClickEventFinished( |
| + const NotificationClickDispatchCompleteCallback& callback, |
| + const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, |
| + ServiceWorkerStatusCode service_worker_status) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS; |
| + switch (service_worker_status) { |
| + case SERVICE_WORKER_OK: |
| + // Success status was initialized above. |
| + break; |
| + case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED: |
| + status = PERSISTENT_NOTIFICATION_STATUS_EVENT_WAITUNTIL_REJECTED; |
| + break; |
| + case SERVICE_WORKER_ERROR_FAILED: |
| + case SERVICE_WORKER_ERROR_ABORT: |
| + case SERVICE_WORKER_ERROR_START_WORKER_FAILED: |
| + case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND: |
| + case SERVICE_WORKER_ERROR_NOT_FOUND: |
| + case SERVICE_WORKER_ERROR_EXISTS: |
| + case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED: |
| + case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED: |
| + case SERVICE_WORKER_ERROR_IPC_FAILED: |
| + case SERVICE_WORKER_ERROR_NETWORK: |
| + case SERVICE_WORKER_ERROR_SECURITY: |
| + status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR; |
| + break; |
| + } |
| + |
| + BrowserThread::PostTask(BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(callback, status)); |
| +} |
| + |
| +// Dispatches the notificationclick on |service_worker_registration| if the |
| +// registration was available. Must be called on the IO thread. |
| +void DispatchNotificationClickEvent( |
| + const std::string& notification_id, |
| + const ShowDesktopNotificationHostMsgParams& notification_data, |
| + const NotificationClickDispatchCompleteCallback& callback, |
| + ServiceWorkerStatusCode service_worker_status, |
| + const scoped_refptr<ServiceWorkerRegistration>& |
| + service_worker_registration) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + if (service_worker_status == SERVICE_WORKER_OK) { |
| + base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback = |
| + base::Bind(&NotificationClickEventFinished, |
| + callback, |
| + service_worker_registration); |
| + service_worker_registration->active_version() |
| + ->DispatchNotificationClickEvent(dispatch_event_callback, |
| + notification_id, |
| + notification_data); |
| + return; |
| + } |
| + |
| + PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS; |
| + switch (service_worker_status) { |
| + case SERVICE_WORKER_ERROR_NOT_FOUND: |
| + status = PERSISTENT_NOTIFICATION_STATUS_NO_SERVICE_WORKER; |
| + break; |
| + case SERVICE_WORKER_ERROR_FAILED: |
| + case SERVICE_WORKER_ERROR_ABORT: |
| + case SERVICE_WORKER_ERROR_START_WORKER_FAILED: |
| + case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND: |
| + case SERVICE_WORKER_ERROR_EXISTS: |
| + case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED: |
| + case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED: |
| + case SERVICE_WORKER_ERROR_IPC_FAILED: |
| + case SERVICE_WORKER_ERROR_NETWORK: |
| + case SERVICE_WORKER_ERROR_SECURITY: |
| + case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED: |
| + status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR; |
| + break; |
| + case SERVICE_WORKER_OK: |
| + NOTREACHED(); |
| + break; |
| + } |
| + |
| + BrowserThread::PostTask(BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(callback, status)); |
|
Michael van Ouwerkerk
2014/12/08 15:13:42
Nit: there are multiple callbacks in this function
Peter Beverloo
2014/12/08 17:27:07
Done.
|
| +} |
| + |
| +// Finds the ServiceWorkerRegistration associated with the |origin| and |
| +// |service_worker_registration_id|. Must be called on the IO thread. |
| +void FindServiceWorkerRegistration( |
| + const GURL& origin, |
| + int64 service_worker_registration_id, |
| + const std::string& notification_id, |
| + const ShowDesktopNotificationHostMsgParams& notification_data, |
| + const NotificationClickDispatchCompleteCallback& callback, |
| + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + service_worker_context->context()->storage()->FindRegistrationForId( |
| + service_worker_registration_id, |
| + origin, |
| + base::Bind(&DispatchNotificationClickEvent, |
| + notification_id, |
| + notification_data, |
| + callback)); |
| +} |
| + |
| +} // namespace |
| + |
| +// static |
| +NotificationEventDispatcher* NotificationEventDispatcher::GetInstance() { |
| + return NotificationEventDispatcherImpl::GetInstance(); |
| +} |
| + |
| +NotificationEventDispatcherImpl* |
| +NotificationEventDispatcherImpl::GetInstance() { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + return Singleton<NotificationEventDispatcherImpl>::get(); |
| +} |
| + |
| +NotificationEventDispatcherImpl::NotificationEventDispatcherImpl() {} |
| + |
| +NotificationEventDispatcherImpl::~NotificationEventDispatcherImpl() {} |
| + |
| +void NotificationEventDispatcherImpl::DispatchNotificationClickEvent( |
|
Michael van Ouwerkerk
2014/12/08 15:13:42
Nit: this has the same name as a function in an an
Peter Beverloo
2014/12/08 17:27:07
Done.
|
| + BrowserContext* browser_context, |
| + const GURL& origin, |
| + int64 service_worker_registration_id, |
| + const std::string& notification_id, |
| + const ShowDesktopNotificationHostMsgParams& notification_data, |
| + const NotificationClickDispatchCompleteCallback& callback) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + |
| + StoragePartition* partition = |
| + BrowserContext::GetStoragePartitionForSite(browser_context, origin); |
| + scoped_refptr<ServiceWorkerContextWrapper> service_worker_context = |
| + static_cast<ServiceWorkerContextWrapper*>( |
| + partition->GetServiceWorkerContext()); |
| + BrowserThread::PostTask( |
| + BrowserThread::IO, |
| + FROM_HERE, |
| + base::Bind(&FindServiceWorkerRegistration, |
| + origin, |
| + service_worker_registration_id, |
| + notification_id, |
| + notification_data, |
| + callback, |
| + service_worker_context)); |
| +} |
| + |
| +} // namespace content |