Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / notifications / notification_event_dispatcher_impl.cc
bloba9cdd2e383709e14b6ae7ae5cee5e95afc1aa141
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/notifications/notification_event_dispatcher_impl.h"
7 #include "base/callback.h"
8 #include "content/browser/service_worker/service_worker_context_wrapper.h"
9 #include "content/browser/service_worker/service_worker_registration.h"
10 #include "content/browser/service_worker/service_worker_storage.h"
11 #include "content/public/browser/browser_context.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/storage_partition.h"
14 #include "content/public/common/platform_notification_data.h"
16 namespace content {
17 namespace {
19 using NotificationClickDispatchCompleteCallback =
20 NotificationEventDispatcher::NotificationClickDispatchCompleteCallback;
22 // To be called when the notificationclick event has finished executing. Will
23 // post a task to call |dispatch_complete_callback| on the UI thread.
24 void NotificationClickEventFinished(
25 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
26 const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
27 ServiceWorkerStatusCode service_worker_status) {
28 DCHECK_CURRENTLY_ON(BrowserThread::IO);
30 PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS;
31 switch (service_worker_status) {
32 case SERVICE_WORKER_OK:
33 // Success status was initialized above.
34 break;
35 case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
36 status = PERSISTENT_NOTIFICATION_STATUS_EVENT_WAITUNTIL_REJECTED;
37 break;
38 case SERVICE_WORKER_ERROR_FAILED:
39 case SERVICE_WORKER_ERROR_ABORT:
40 case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
41 case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
42 case SERVICE_WORKER_ERROR_NOT_FOUND:
43 case SERVICE_WORKER_ERROR_EXISTS:
44 case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
45 case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
46 case SERVICE_WORKER_ERROR_IPC_FAILED:
47 case SERVICE_WORKER_ERROR_NETWORK:
48 case SERVICE_WORKER_ERROR_SECURITY:
49 case SERVICE_WORKER_ERROR_STATE:
50 case SERVICE_WORKER_ERROR_TIMEOUT:
51 case SERVICE_WORKER_ERROR_MAX_VALUE:
52 status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR;
53 break;
56 BrowserThread::PostTask(BrowserThread::UI,
57 FROM_HERE,
58 base::Bind(dispatch_complete_callback, status));
61 // Dispatches the notificationclick on |service_worker_registration| if the
62 // registration was available. Must be called on the IO thread.
63 void DispatchNotificationClickEventOnRegistration(
64 const std::string& notification_id,
65 const PlatformNotificationData& notification_data,
66 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
67 ServiceWorkerStatusCode service_worker_status,
68 const scoped_refptr<ServiceWorkerRegistration>&
69 service_worker_registration) {
70 DCHECK_CURRENTLY_ON(BrowserThread::IO);
71 if (service_worker_status == SERVICE_WORKER_OK) {
72 base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback =
73 base::Bind(&NotificationClickEventFinished,
74 dispatch_complete_callback,
75 service_worker_registration);
76 service_worker_registration->active_version()
77 ->DispatchNotificationClickEvent(dispatch_event_callback,
78 notification_id,
79 notification_data);
80 return;
83 PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS;
84 switch (service_worker_status) {
85 case SERVICE_WORKER_ERROR_NOT_FOUND:
86 status = PERSISTENT_NOTIFICATION_STATUS_NO_SERVICE_WORKER;
87 break;
88 case SERVICE_WORKER_ERROR_FAILED:
89 case SERVICE_WORKER_ERROR_ABORT:
90 case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
91 case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
92 case SERVICE_WORKER_ERROR_EXISTS:
93 case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
94 case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
95 case SERVICE_WORKER_ERROR_IPC_FAILED:
96 case SERVICE_WORKER_ERROR_NETWORK:
97 case SERVICE_WORKER_ERROR_SECURITY:
98 case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
99 case SERVICE_WORKER_ERROR_STATE:
100 case SERVICE_WORKER_ERROR_TIMEOUT:
101 case SERVICE_WORKER_ERROR_MAX_VALUE:
102 status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR;
103 break;
104 case SERVICE_WORKER_OK:
105 NOTREACHED();
106 break;
109 BrowserThread::PostTask(BrowserThread::UI,
110 FROM_HERE,
111 base::Bind(dispatch_complete_callback, status));
114 // Finds the ServiceWorkerRegistration associated with the |origin| and
115 // |service_worker_registration_id|. Must be called on the IO thread.
116 void FindServiceWorkerRegistration(
117 const GURL& origin,
118 int64 service_worker_registration_id,
119 const std::string& notification_id,
120 const PlatformNotificationData& notification_data,
121 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
122 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) {
123 DCHECK_CURRENTLY_ON(BrowserThread::IO);
124 service_worker_context->context()->storage()->FindRegistrationForId(
125 service_worker_registration_id,
126 origin,
127 base::Bind(&DispatchNotificationClickEventOnRegistration,
128 notification_id,
129 notification_data,
130 dispatch_complete_callback));
133 } // namespace
135 // static
136 NotificationEventDispatcher* NotificationEventDispatcher::GetInstance() {
137 return NotificationEventDispatcherImpl::GetInstance();
140 NotificationEventDispatcherImpl*
141 NotificationEventDispatcherImpl::GetInstance() {
142 DCHECK_CURRENTLY_ON(BrowserThread::UI);
143 return Singleton<NotificationEventDispatcherImpl>::get();
146 NotificationEventDispatcherImpl::NotificationEventDispatcherImpl() {}
148 NotificationEventDispatcherImpl::~NotificationEventDispatcherImpl() {}
150 void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
151 BrowserContext* browser_context,
152 const GURL& origin,
153 int64 service_worker_registration_id,
154 const std::string& notification_id,
155 const PlatformNotificationData& notification_data,
156 const NotificationClickDispatchCompleteCallback&
157 dispatch_complete_callback) {
158 DCHECK_CURRENTLY_ON(BrowserThread::UI);
160 StoragePartition* partition =
161 BrowserContext::GetStoragePartitionForSite(browser_context, origin);
162 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
163 static_cast<ServiceWorkerContextWrapper*>(
164 partition->GetServiceWorkerContext());
165 BrowserThread::PostTask(
166 BrowserThread::IO,
167 FROM_HERE,
168 base::Bind(&FindServiceWorkerRegistration,
169 origin,
170 service_worker_registration_id,
171 notification_id,
172 notification_data,
173 dispatch_complete_callback,
174 service_worker_context));
177 } // namespace content