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. 4 5 #include "content/browser/push_messaging_router.h" 6 7 #include "base/bind.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 15 namespace content { 16 17 // static 18 void PushMessagingRouter::DeliverMessage( 19 BrowserContext* browser_context, 20 const GURL& origin, 21 int64 service_worker_registration_id, 22 const std::string& data, 23 const DeliverMessageCallback& deliver_message_callback) { 24 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 25 StoragePartition* partition = 26 BrowserContext::GetStoragePartitionForSite(browser_context, origin); 27 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context = 28 static_cast<ServiceWorkerContextWrapper*>( 29 partition->GetServiceWorkerContext()); 30 BrowserThread::PostTask( 31 BrowserThread::IO, 32 FROM_HERE, 33 base::Bind(&PushMessagingRouter::FindServiceWorkerRegistration, 34 origin, 35 service_worker_registration_id, 36 data, 37 deliver_message_callback, 38 service_worker_context)); 39 } 40 41 // static 42 void PushMessagingRouter::FindServiceWorkerRegistration( 43 const GURL& origin, 44 int64 service_worker_registration_id, 45 const std::string& data, 46 const DeliverMessageCallback& deliver_message_callback, 47 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context) { 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 49 // Try to acquire the registration from storage. If it's already live we'll 50 // receive it right away. If not, it will be revived from storage. 51 service_worker_context->context()->storage()->FindRegistrationForId( 52 service_worker_registration_id, 53 origin, 54 base::Bind(&PushMessagingRouter::FindServiceWorkerRegistrationCallback, 55 data, 56 deliver_message_callback)); 57 } 58 59 // static 60 void PushMessagingRouter::FindServiceWorkerRegistrationCallback( 61 const std::string& data, 62 const DeliverMessageCallback& deliver_message_callback, 63 ServiceWorkerStatusCode service_worker_status, 64 const scoped_refptr<ServiceWorkerRegistration>& 65 service_worker_registration) { 66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 67 if (service_worker_status == SERVICE_WORKER_OK) { 68 // Hold on to the service worker registration in the callback to keep it 69 // alive until the callback dies. Otherwise the registration could be 70 // released when this method returns - before the event is delivered to the 71 // service worker. 72 base::Callback<void(ServiceWorkerStatusCode)> dispatch_event_callback = 73 base::Bind(&PushMessagingRouter::DeliverMessageEnd, 74 deliver_message_callback, 75 service_worker_registration); 76 service_worker_registration->active_version()->DispatchPushEvent( 77 dispatch_event_callback, data); 78 } else { 79 // TODO(mvanouwerkerk): UMA logging. 80 BrowserThread::PostTask( 81 BrowserThread::UI, 82 FROM_HERE, 83 base::Bind( 84 deliver_message_callback, 85 PUSH_MESSAGING_STATUS_MESSAGE_DELIVERY_FAILED_NO_SERVICE_WORKER)); 86 } 87 } 88 89 // static 90 void PushMessagingRouter::DeliverMessageEnd( 91 const DeliverMessageCallback& deliver_message_callback, 92 const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration, 93 ServiceWorkerStatusCode service_worker_status) { 94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 95 // TODO(mvanouwerkerk): UMA logging. 96 PushMessagingStatus push_messaging_status = 97 service_worker_status == SERVICE_WORKER_OK 98 ? PUSH_MESSAGING_STATUS_OK 99 : PUSH_MESSAGING_STATUS_MESSAGE_DELIVERY_FAILED_SERVICE_WORKER_ERROR; 100 BrowserThread::PostTask( 101 BrowserThread::UI, 102 FROM_HERE, 103 base::Bind(deliver_message_callback, push_messaging_status)); 104 } 105 106 } // namespace content 107