[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / notifications / notification_event_dispatcher_impl.cc
blob382991cf49212824804ed18ce60286a6d1eca42b
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/notifications/platform_notification_context_impl.h"
9 #include "content/browser/service_worker/service_worker_context_wrapper.h"
10 #include "content/browser/service_worker/service_worker_registration.h"
11 #include "content/browser/service_worker/service_worker_storage.h"
12 #include "content/public/browser/browser_context.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/notification_database_data.h"
15 #include "content/public/browser/storage_partition.h"
16 #include "content/public/common/platform_notification_data.h"
18 namespace content {
19 namespace {
21 using NotificationClickDispatchCompleteCallback =
22 NotificationEventDispatcher::NotificationClickDispatchCompleteCallback;
24 // To be called when the notificationclick event has finished executing. Will
25 // post a task to call |dispatch_complete_callback| on the UI thread.
26 void NotificationClickEventFinished(
27 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
28 const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
29 ServiceWorkerStatusCode service_worker_status) {
30 DCHECK_CURRENTLY_ON(BrowserThread::IO);
32 PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS;
33 switch (service_worker_status) {
34 case SERVICE_WORKER_OK:
35 // Success status was initialized above.
36 break;
37 case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
38 status = PERSISTENT_NOTIFICATION_STATUS_EVENT_WAITUNTIL_REJECTED;
39 break;
40 case SERVICE_WORKER_ERROR_FAILED:
41 case SERVICE_WORKER_ERROR_ABORT:
42 case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
43 case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
44 case SERVICE_WORKER_ERROR_NOT_FOUND:
45 case SERVICE_WORKER_ERROR_EXISTS:
46 case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
47 case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
48 case SERVICE_WORKER_ERROR_IPC_FAILED:
49 case SERVICE_WORKER_ERROR_NETWORK:
50 case SERVICE_WORKER_ERROR_SECURITY:
51 case SERVICE_WORKER_ERROR_STATE:
52 case SERVICE_WORKER_ERROR_TIMEOUT:
53 case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
54 case SERVICE_WORKER_ERROR_DISK_CACHE:
55 case SERVICE_WORKER_ERROR_REDUNDANT:
56 case SERVICE_WORKER_ERROR_DISALLOWED:
57 case SERVICE_WORKER_ERROR_MAX_VALUE:
58 status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR;
59 break;
62 BrowserThread::PostTask(BrowserThread::UI,
63 FROM_HERE,
64 base::Bind(dispatch_complete_callback, status));
67 // Dispatches the notificationclick on |service_worker_registration| if the
68 // registration was available. Must be called on the IO thread.
69 void DispatchNotificationClickEventOnRegistration(
70 const NotificationDatabaseData& notification_database_data,
71 int action_index,
72 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
73 ServiceWorkerStatusCode service_worker_status,
74 const scoped_refptr<ServiceWorkerRegistration>&
75 service_worker_registration) {
76 DCHECK_CURRENTLY_ON(BrowserThread::IO);
77 if (service_worker_status == SERVICE_WORKER_OK) {
78 base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback =
79 base::Bind(&NotificationClickEventFinished,
80 dispatch_complete_callback,
81 service_worker_registration);
83 service_worker_registration->active_version()->
84 DispatchNotificationClickEvent(
85 dispatch_event_callback,
86 notification_database_data.notification_id,
87 notification_database_data.notification_data,
88 action_index);
89 return;
92 PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS;
93 switch (service_worker_status) {
94 case SERVICE_WORKER_ERROR_NOT_FOUND:
95 status = PERSISTENT_NOTIFICATION_STATUS_NO_SERVICE_WORKER;
96 break;
97 case SERVICE_WORKER_ERROR_FAILED:
98 case SERVICE_WORKER_ERROR_ABORT:
99 case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
100 case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
101 case SERVICE_WORKER_ERROR_EXISTS:
102 case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
103 case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
104 case SERVICE_WORKER_ERROR_IPC_FAILED:
105 case SERVICE_WORKER_ERROR_NETWORK:
106 case SERVICE_WORKER_ERROR_SECURITY:
107 case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
108 case SERVICE_WORKER_ERROR_STATE:
109 case SERVICE_WORKER_ERROR_TIMEOUT:
110 case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
111 case SERVICE_WORKER_ERROR_DISK_CACHE:
112 case SERVICE_WORKER_ERROR_REDUNDANT:
113 case SERVICE_WORKER_ERROR_DISALLOWED:
114 case SERVICE_WORKER_ERROR_MAX_VALUE:
115 status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR;
116 break;
117 case SERVICE_WORKER_OK:
118 NOTREACHED();
119 break;
122 BrowserThread::PostTask(BrowserThread::UI,
123 FROM_HERE,
124 base::Bind(dispatch_complete_callback, status));
127 // Finds the ServiceWorkerRegistration associated with the |origin| and
128 // |service_worker_registration_id|. Must be called on the IO thread.
129 void FindServiceWorkerRegistration(
130 const GURL& origin,
131 int action_index,
132 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
133 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
134 bool success,
135 const NotificationDatabaseData& notification_database_data) {
136 DCHECK_CURRENTLY_ON(BrowserThread::IO);
137 if (!success) {
138 BrowserThread::PostTask(
139 BrowserThread::UI,
140 FROM_HERE,
141 base::Bind(dispatch_complete_callback,
142 PERSISTENT_NOTIFICATION_STATUS_DATABASE_ERROR));
143 return;
146 service_worker_context->FindRegistrationForId(
147 notification_database_data.service_worker_registration_id,
148 origin,
149 base::Bind(&DispatchNotificationClickEventOnRegistration,
150 notification_database_data, action_index,
151 dispatch_complete_callback));
154 // Reads the data associated with the |persistent_notification_id| belonging to
155 // |origin| from the notification context.
156 void ReadNotificationDatabaseData(
157 int64_t persistent_notification_id,
158 const GURL& origin,
159 int action_index,
160 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
161 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
162 scoped_refptr<PlatformNotificationContextImpl> notification_context) {
163 DCHECK_CURRENTLY_ON(BrowserThread::IO);
164 notification_context->ReadNotificationData(
165 persistent_notification_id,
166 origin,
167 base::Bind(&FindServiceWorkerRegistration,
168 origin, action_index, dispatch_complete_callback,
169 service_worker_context));
172 } // namespace
174 // static
175 NotificationEventDispatcher* NotificationEventDispatcher::GetInstance() {
176 return NotificationEventDispatcherImpl::GetInstance();
179 NotificationEventDispatcherImpl*
180 NotificationEventDispatcherImpl::GetInstance() {
181 DCHECK_CURRENTLY_ON(BrowserThread::UI);
182 return base::Singleton<NotificationEventDispatcherImpl>::get();
185 NotificationEventDispatcherImpl::NotificationEventDispatcherImpl() {}
187 NotificationEventDispatcherImpl::~NotificationEventDispatcherImpl() {}
189 void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
190 BrowserContext* browser_context,
191 int64_t persistent_notification_id,
192 const GURL& origin,
193 int action_index,
194 const NotificationClickDispatchCompleteCallback&
195 dispatch_complete_callback) {
196 DCHECK_CURRENTLY_ON(BrowserThread::UI);
197 DCHECK_GT(persistent_notification_id, 0);
198 DCHECK(origin.is_valid());
200 StoragePartition* partition =
201 BrowserContext::GetStoragePartitionForSite(browser_context, origin);
203 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
204 static_cast<ServiceWorkerContextWrapper*>(
205 partition->GetServiceWorkerContext());
206 scoped_refptr<PlatformNotificationContextImpl> notification_context =
207 static_cast<PlatformNotificationContextImpl*>(
208 partition->GetPlatformNotificationContext());
210 BrowserThread::PostTask(
211 BrowserThread::IO,
212 FROM_HERE,
213 base::Bind(&ReadNotificationDatabaseData,
214 persistent_notification_id,
215 origin,
216 action_index,
217 dispatch_complete_callback,
218 service_worker_context,
219 notification_context));
222 } // namespace content