Add ICU message format support
[chromium-blink-merge.git] / content / browser / push_messaging / push_messaging_router.cc
blob94510a0867171b0677649eb848bd2245dcf2ea36
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"
7 #include <string>
9 #include "base/bind.h"
10 #include "content/browser/service_worker/service_worker_context_wrapper.h"
11 #include "content/browser/service_worker/service_worker_registration.h"
12 #include "content/browser/service_worker/service_worker_storage.h"
13 #include "content/common/service_worker/service_worker_status_code.h"
14 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/storage_partition.h"
18 namespace content {
20 namespace {
22 void RunDeliverCallback(
23 const PushMessagingRouter::DeliverMessageCallback& deliver_message_callback,
24 PushDeliveryStatus delivery_status) {
25 BrowserThread::PostTask(
26 BrowserThread::UI, FROM_HERE,
27 base::Bind(deliver_message_callback, delivery_status));
30 } // namespace
32 // static
33 void PushMessagingRouter::DeliverMessage(
34 BrowserContext* browser_context,
35 const GURL& origin,
36 int64 service_worker_registration_id,
37 const std::string& data,
38 const DeliverMessageCallback& deliver_message_callback) {
39 DCHECK_CURRENTLY_ON(BrowserThread::UI);
40 StoragePartition* partition =
41 BrowserContext::GetStoragePartitionForSite(browser_context, origin);
42 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context =
43 static_cast<ServiceWorkerContextWrapper*>(
44 partition->GetServiceWorkerContext());
45 BrowserThread::PostTask(
46 BrowserThread::IO,
47 FROM_HERE,
48 base::Bind(&PushMessagingRouter::FindServiceWorkerRegistration,
49 origin,
50 service_worker_registration_id,
51 data,
52 deliver_message_callback,
53 service_worker_context));
56 // static
57 void PushMessagingRouter::FindServiceWorkerRegistration(
58 const GURL& origin,
59 int64 service_worker_registration_id,
60 const std::string& data,
61 const DeliverMessageCallback& deliver_message_callback,
62 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) {
63 DCHECK_CURRENTLY_ON(BrowserThread::IO);
64 // Try to acquire the registration from storage. If it's already live we'll
65 // receive it right away. If not, it will be revived from storage.
66 service_worker_context->FindRegistrationForId(
67 service_worker_registration_id,
68 origin,
69 base::Bind(&PushMessagingRouter::FindServiceWorkerRegistrationCallback,
70 data,
71 deliver_message_callback));
74 // static
75 void PushMessagingRouter::FindServiceWorkerRegistrationCallback(
76 const std::string& data,
77 const DeliverMessageCallback& deliver_message_callback,
78 ServiceWorkerStatusCode service_worker_status,
79 const scoped_refptr<ServiceWorkerRegistration>&
80 service_worker_registration) {
81 DCHECK_CURRENTLY_ON(BrowserThread::IO);
82 // TODO(mvanouwerkerk): UMA logging.
83 if (service_worker_status != SERVICE_WORKER_OK) {
84 RunDeliverCallback(deliver_message_callback,
85 PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER);
86 return;
89 ServiceWorkerVersion* version = service_worker_registration->active_version();
90 if (!version) {
91 // Using NO_SERVICE_WORKER status will unsubscribe with GCM, so don't use it
92 // if we have a waiting version in the hopper. On the other hand, if there
93 // is no waiting version, it's an unexpected error case: we should have been
94 // informed the registration went away (but we may not have been:
95 // crbug.com/402458)
96 // TODO(falken): Promote the waiting version instead of returning error.
97 if (service_worker_registration->waiting_version()) {
98 RunDeliverCallback(deliver_message_callback,
99 PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR);
100 } else {
101 RunDeliverCallback(deliver_message_callback,
102 PUSH_DELIVERY_STATUS_NO_SERVICE_WORKER);
104 return;
107 // Hold on to the service worker registration in the callback to keep it
108 // alive until the callback dies. Otherwise the registration could be
109 // released when this method returns - before the event is delivered to the
110 // service worker.
111 base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback =
112 base::Bind(&PushMessagingRouter::DeliverMessageEnd,
113 deliver_message_callback, service_worker_registration);
114 version->DispatchPushEvent(dispatch_event_callback, data);
117 // static
118 void PushMessagingRouter::DeliverMessageEnd(
119 const DeliverMessageCallback& deliver_message_callback,
120 const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
121 ServiceWorkerStatusCode service_worker_status) {
122 DCHECK_CURRENTLY_ON(BrowserThread::IO);
123 // TODO(mvanouwerkerk): UMA logging.
124 PushDeliveryStatus delivery_status =
125 PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR;
126 switch (service_worker_status) {
127 case SERVICE_WORKER_OK:
128 delivery_status = PUSH_DELIVERY_STATUS_SUCCESS;
129 break;
130 case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
131 delivery_status = PUSH_DELIVERY_STATUS_EVENT_WAITUNTIL_REJECTED;
132 break;
133 case SERVICE_WORKER_ERROR_FAILED:
134 case SERVICE_WORKER_ERROR_ABORT:
135 case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
136 case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
137 case SERVICE_WORKER_ERROR_NOT_FOUND:
138 case SERVICE_WORKER_ERROR_IPC_FAILED:
139 case SERVICE_WORKER_ERROR_TIMEOUT:
140 case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
141 case SERVICE_WORKER_ERROR_DISK_CACHE:
142 case SERVICE_WORKER_ERROR_REDUNDANT:
143 delivery_status = PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR;
144 break;
145 case SERVICE_WORKER_ERROR_EXISTS:
146 case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
147 case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
148 case SERVICE_WORKER_ERROR_NETWORK:
149 case SERVICE_WORKER_ERROR_SECURITY:
150 case SERVICE_WORKER_ERROR_STATE:
151 case SERVICE_WORKER_ERROR_MAX_VALUE:
152 NOTREACHED() << "Got unexpected error code: " << service_worker_status
153 << " " << ServiceWorkerStatusToString(service_worker_status);
154 delivery_status = PUSH_DELIVERY_STATUS_SERVICE_WORKER_ERROR;
155 break;
157 RunDeliverCallback(deliver_message_callback, delivery_status);
160 } // namespace content