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"
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.
35 case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED
:
36 status
= PERSISTENT_NOTIFICATION_STATUS_EVENT_WAITUNTIL_REJECTED
;
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 status
= PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR
;
54 BrowserThread::PostTask(BrowserThread::UI
,
56 base::Bind(dispatch_complete_callback
, status
));
59 // Dispatches the notificationclick on |service_worker_registration| if the
60 // registration was available. Must be called on the IO thread.
61 void DispatchNotificationClickEventOnRegistration(
62 const std::string
& notification_id
,
63 const PlatformNotificationData
& notification_data
,
64 const NotificationClickDispatchCompleteCallback
& dispatch_complete_callback
,
65 ServiceWorkerStatusCode service_worker_status
,
66 const scoped_refptr
<ServiceWorkerRegistration
>&
67 service_worker_registration
) {
68 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
69 if (service_worker_status
== SERVICE_WORKER_OK
) {
70 base::Callback
<void(ServiceWorkerStatusCode
)> dispatch_event_callback
=
71 base::Bind(&NotificationClickEventFinished
,
72 dispatch_complete_callback
,
73 service_worker_registration
);
74 service_worker_registration
->active_version()
75 ->DispatchNotificationClickEvent(dispatch_event_callback
,
81 PersistentNotificationStatus status
= PERSISTENT_NOTIFICATION_STATUS_SUCCESS
;
82 switch (service_worker_status
) {
83 case SERVICE_WORKER_ERROR_NOT_FOUND
:
84 status
= PERSISTENT_NOTIFICATION_STATUS_NO_SERVICE_WORKER
;
86 case SERVICE_WORKER_ERROR_FAILED
:
87 case SERVICE_WORKER_ERROR_ABORT
:
88 case SERVICE_WORKER_ERROR_START_WORKER_FAILED
:
89 case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND
:
90 case SERVICE_WORKER_ERROR_EXISTS
:
91 case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED
:
92 case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED
:
93 case SERVICE_WORKER_ERROR_IPC_FAILED
:
94 case SERVICE_WORKER_ERROR_NETWORK
:
95 case SERVICE_WORKER_ERROR_SECURITY
:
96 case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED
:
97 case SERVICE_WORKER_ERROR_STATE
:
98 status
= PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR
;
100 case SERVICE_WORKER_OK
:
105 BrowserThread::PostTask(BrowserThread::UI
,
107 base::Bind(dispatch_complete_callback
, status
));
110 // Finds the ServiceWorkerRegistration associated with the |origin| and
111 // |service_worker_registration_id|. Must be called on the IO thread.
112 void FindServiceWorkerRegistration(
114 int64 service_worker_registration_id
,
115 const std::string
& notification_id
,
116 const PlatformNotificationData
& notification_data
,
117 const NotificationClickDispatchCompleteCallback
& dispatch_complete_callback
,
118 scoped_refptr
<ServiceWorkerContextWrapper
> service_worker_context
) {
119 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
120 service_worker_context
->context()->storage()->FindRegistrationForId(
121 service_worker_registration_id
,
123 base::Bind(&DispatchNotificationClickEventOnRegistration
,
126 dispatch_complete_callback
));
132 NotificationEventDispatcher
* NotificationEventDispatcher::GetInstance() {
133 return NotificationEventDispatcherImpl::GetInstance();
136 NotificationEventDispatcherImpl
*
137 NotificationEventDispatcherImpl::GetInstance() {
138 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
139 return Singleton
<NotificationEventDispatcherImpl
>::get();
142 NotificationEventDispatcherImpl::NotificationEventDispatcherImpl() {}
144 NotificationEventDispatcherImpl::~NotificationEventDispatcherImpl() {}
146 void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
147 BrowserContext
* browser_context
,
149 int64 service_worker_registration_id
,
150 const std::string
& notification_id
,
151 const PlatformNotificationData
& notification_data
,
152 const NotificationClickDispatchCompleteCallback
&
153 dispatch_complete_callback
) {
154 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
156 StoragePartition
* partition
=
157 BrowserContext::GetStoragePartitionForSite(browser_context
, origin
);
158 scoped_refptr
<ServiceWorkerContextWrapper
> service_worker_context
=
159 static_cast<ServiceWorkerContextWrapper
*>(
160 partition
->GetServiceWorkerContext());
161 BrowserThread::PostTask(
164 base::Bind(&FindServiceWorkerRegistration
,
166 service_worker_registration_id
,
169 dispatch_complete_callback
,
170 service_worker_context
));
173 } // namespace content