Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / content / browser / notifications / notification_event_dispatcher_impl.cc
blob78d2a85e16f708ea0774816193fc8f54fe29fcca
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_MAX_VALUE:
55 status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR;
56 break;
59 BrowserThread::PostTask(BrowserThread::UI,
60 FROM_HERE,
61 base::Bind(dispatch_complete_callback, status));
64 // Dispatches the notificationclick on |service_worker_registration| if the
65 // registration was available. Must be called on the IO thread.
66 void DispatchNotificationClickEventOnRegistration(
67 const NotificationDatabaseData& notification_database_data,
68 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
69 ServiceWorkerStatusCode service_worker_status,
70 const scoped_refptr<ServiceWorkerRegistration>&
71 service_worker_registration) {
72 DCHECK_CURRENTLY_ON(BrowserThread::IO);
73 if (service_worker_status == SERVICE_WORKER_OK) {
74 base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback =
75 base::Bind(&NotificationClickEventFinished,
76 dispatch_complete_callback,
77 service_worker_registration);
79 service_worker_registration->active_version()->
80 DispatchNotificationClickEvent(
81 dispatch_event_callback,
82 notification_database_data.notification_id,
83 notification_database_data.notification_data);
84 return;
87 PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS;
88 switch (service_worker_status) {
89 case SERVICE_WORKER_ERROR_NOT_FOUND:
90 status = PERSISTENT_NOTIFICATION_STATUS_NO_SERVICE_WORKER;
91 break;
92 case SERVICE_WORKER_ERROR_FAILED:
93 case SERVICE_WORKER_ERROR_ABORT:
94 case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
95 case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
96 case SERVICE_WORKER_ERROR_EXISTS:
97 case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
98 case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
99 case SERVICE_WORKER_ERROR_IPC_FAILED:
100 case SERVICE_WORKER_ERROR_NETWORK:
101 case SERVICE_WORKER_ERROR_SECURITY:
102 case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
103 case SERVICE_WORKER_ERROR_STATE:
104 case SERVICE_WORKER_ERROR_TIMEOUT:
105 case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
106 case SERVICE_WORKER_ERROR_MAX_VALUE:
107 status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR;
108 break;
109 case SERVICE_WORKER_OK:
110 NOTREACHED();
111 break;
114 BrowserThread::PostTask(BrowserThread::UI,
115 FROM_HERE,
116 base::Bind(dispatch_complete_callback, status));
119 // Finds the ServiceWorkerRegistration associated with the |origin| and
120 // |service_worker_registration_id|. Must be called on the IO thread.
121 void FindServiceWorkerRegistration(
122 const GURL& origin,
123 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
124 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
125 bool success,
126 const NotificationDatabaseData& notification_database_data) {
127 DCHECK_CURRENTLY_ON(BrowserThread::IO);
128 if (!success) {
129 BrowserThread::PostTask(
130 BrowserThread::UI,
131 FROM_HERE,
132 base::Bind(dispatch_complete_callback,
133 PERSISTENT_NOTIFICATION_STATUS_DATABASE_ERROR));
134 return;
137 service_worker_context->FindRegistrationForId(
138 notification_database_data.service_worker_registration_id,
139 origin,
140 base::Bind(&DispatchNotificationClickEventOnRegistration,
141 notification_database_data,
142 dispatch_complete_callback));
145 // Reads the data associated with the |persistent_notification_id| belonging to
146 // |origin| from the notification context.
147 void ReadNotificationDatabaseData(
148 int64_t persistent_notification_id,
149 const GURL& origin,
150 const NotificationClickDispatchCompleteCallback& dispatch_complete_callback,
151 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
152 scoped_refptr<PlatformNotificationContextImpl> notification_context) {
153 DCHECK_CURRENTLY_ON(BrowserThread::IO);
154 notification_context->ReadNotificationData(
155 persistent_notification_id,
156 origin,
157 base::Bind(&FindServiceWorkerRegistration,
158 origin, dispatch_complete_callback, service_worker_context));
161 } // namespace
163 // static
164 NotificationEventDispatcher* NotificationEventDispatcher::GetInstance() {
165 return NotificationEventDispatcherImpl::GetInstance();
168 NotificationEventDispatcherImpl*
169 NotificationEventDispatcherImpl::GetInstance() {
170 DCHECK_CURRENTLY_ON(BrowserThread::UI);
171 return Singleton<NotificationEventDispatcherImpl>::get();
174 NotificationEventDispatcherImpl::NotificationEventDispatcherImpl() {}
176 NotificationEventDispatcherImpl::~NotificationEventDispatcherImpl() {}
178 void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
179 BrowserContext* browser_context,
180 int64_t persistent_notification_id,
181 const GURL& origin,
182 const NotificationClickDispatchCompleteCallback&
183 dispatch_complete_callback) {
184 DCHECK_CURRENTLY_ON(BrowserThread::UI);
185 DCHECK_GT(persistent_notification_id, 0);
186 DCHECK(origin.is_valid());
188 StoragePartition* partition =
189 BrowserContext::GetStoragePartitionForSite(browser_context, origin);
191 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
192 static_cast<ServiceWorkerContextWrapper*>(
193 partition->GetServiceWorkerContext());
194 scoped_refptr<PlatformNotificationContextImpl> notification_context =
195 static_cast<PlatformNotificationContextImpl*>(
196 partition->GetPlatformNotificationContext());
198 BrowserThread::PostTask(
199 BrowserThread::IO,
200 FROM_HERE,
201 base::Bind(&ReadNotificationDatabaseData,
202 persistent_notification_id,
203 origin,
204 dispatch_complete_callback,
205 service_worker_context,
206 notification_context));
209 } // namespace content