Home | History | Annotate | Download | only in browser
      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