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/push_messaging/push_messaging_router.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/common/service_worker/service_worker_status_code.h"
12 #include "content/public/browser/browser_context.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/storage_partition.h"
19 void PushMessagingRouter::DeliverMessage(
20 BrowserContext
* browser_context
,
22 int64 service_worker_registration_id
,
23 const std::string
& data
,
24 const DeliverMessageCallback
& deliver_message_callback
) {
25 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
26 StoragePartition
* partition
=
27 BrowserContext::GetStoragePartitionForSite(browser_context
, origin
);
28 scoped_refptr
<ServiceWorkerContextWrapper
> service_worker_context
=
29 static_cast<ServiceWorkerContextWrapper
*>(
30 partition
->GetServiceWorkerContext());
31 BrowserThread::PostTask(
34 base::Bind(&PushMessagingRouter::FindServiceWorkerRegistration
,
36 service_worker_registration_id
,
38 deliver_message_callback
,
39 service_worker_context
));
43 void PushMessagingRouter::FindServiceWorkerRegistration(
45 int64 service_worker_registration_id
,
46 const std::string
& data
,
47 const DeliverMessageCallback
& deliver_message_callback
,
48 scoped_refptr
<ServiceWorkerContextWrapper
> service_worker_context
) {
49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
50 // Try to acquire the registration from storage. If it's already live we'll
51 // receive it right away. If not, it will be revived from storage.
52 service_worker_context
->context()->storage()->FindRegistrationForId(
53 service_worker_registration_id
,
55 base::Bind(&PushMessagingRouter::FindServiceWorkerRegistrationCallback
,
57 deliver_message_callback
));
61 void PushMessagingRouter::FindServiceWorkerRegistrationCallback(
62 const std::string
& data
,
63 const DeliverMessageCallback
& deliver_message_callback
,
64 ServiceWorkerStatusCode service_worker_status
,
65 const scoped_refptr
<ServiceWorkerRegistration
>&
66 service_worker_registration
) {
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
68 if (service_worker_status
== SERVICE_WORKER_OK
) {
69 // Hold on to the service worker registration in the callback to keep it
70 // alive until the callback dies. Otherwise the registration could be
71 // released when this method returns - before the event is delivered to the
73 base::Callback
<void(ServiceWorkerStatusCode
)> dispatch_event_callback
=
74 base::Bind(&PushMessagingRouter::DeliverMessageEnd
,
75 deliver_message_callback
,
76 service_worker_registration
);
77 service_worker_registration
->active_version()->DispatchPushEvent(
78 dispatch_event_callback
, data
);
80 // TODO(mvanouwerkerk): UMA logging.
81 BrowserThread::PostTask(BrowserThread::UI
,
83 base::Bind(deliver_message_callback
,
84 PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER
));
89 void PushMessagingRouter::DeliverMessageEnd(
90 const DeliverMessageCallback
& deliver_message_callback
,
91 const scoped_refptr
<ServiceWorkerRegistration
>& service_worker_registration
,
92 ServiceWorkerStatusCode service_worker_status
) {
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
94 // TODO(mvanouwerkerk): UMA logging.
95 PushDeliveryStatus delivery_status
=
96 PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR
;
97 switch (service_worker_status
) {
98 case SERVICE_WORKER_OK
:
99 delivery_status
= PUSH_DELIVERY_STATUS_SUCCESS
;
101 case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED
:
102 delivery_status
= PUSH_DELIVERY_STATUS_EVENT_WAITUNTIL_REJECTED
;
104 case SERVICE_WORKER_ERROR_FAILED
:
105 case SERVICE_WORKER_ERROR_ABORT
:
106 case SERVICE_WORKER_ERROR_START_WORKER_FAILED
:
107 case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND
:
108 case SERVICE_WORKER_ERROR_NOT_FOUND
:
109 case SERVICE_WORKER_ERROR_IPC_FAILED
:
110 delivery_status
= PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR
;
112 case SERVICE_WORKER_ERROR_EXISTS
:
113 case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED
:
114 case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED
:
115 case SERVICE_WORKER_ERROR_NETWORK
:
116 case SERVICE_WORKER_ERROR_SECURITY
:
117 case SERVICE_WORKER_ERROR_STATE
:
118 NOTREACHED() << "Got unexpected error code: " << service_worker_status
119 << " " << ServiceWorkerStatusToString(service_worker_status
);
120 delivery_status
= PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR
;
123 BrowserThread::PostTask(
126 base::Bind(deliver_message_callback
, delivery_status
));
129 } // namespace content