Home | History | Annotate | Download | only in service_worker
      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/service_worker/service_worker_fetch_dispatcher.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/debug/trace_event.h"
      9 #include "content/browser/service_worker/service_worker_version.h"
     10 
     11 namespace content {
     12 
     13 ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
     14     scoped_ptr<ServiceWorkerFetchRequest> request,
     15     ServiceWorkerVersion* version,
     16     const base::Closure& prepare_callback,
     17     const FetchCallback& fetch_callback)
     18     : version_(version),
     19       prepare_callback_(prepare_callback),
     20       fetch_callback_(fetch_callback),
     21       request_(request.Pass()),
     22       weak_factory_(this) {
     23 }
     24 
     25 ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {}
     26 
     27 void ServiceWorkerFetchDispatcher::Run() {
     28   DCHECK(version_->status() == ServiceWorkerVersion::ACTIVATING ||
     29          version_->status() == ServiceWorkerVersion::ACTIVATED)
     30       << version_->status();
     31 
     32   if (version_->status() == ServiceWorkerVersion::ACTIVATING) {
     33     version_->RegisterStatusChangeCallback(
     34         base::Bind(&ServiceWorkerFetchDispatcher::DidWaitActivation,
     35                    weak_factory_.GetWeakPtr()));
     36     return;
     37   }
     38   DispatchFetchEvent();
     39 }
     40 
     41 void ServiceWorkerFetchDispatcher::DidWaitActivation() {
     42   if (version_->status() != ServiceWorkerVersion::ACTIVATED) {
     43     DCHECK_EQ(ServiceWorkerVersion::INSTALLED, version_->status());
     44     DidFailActivation();
     45     return;
     46   }
     47   DispatchFetchEvent();
     48 }
     49 
     50 void ServiceWorkerFetchDispatcher::DidFailActivation() {
     51   // The previous activation seems to have failed, abort the step
     52   // with activate error. (The error should be separately reported
     53   // to the associated documents and association must be dropped
     54   // at this point)
     55   DidFinish(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED,
     56             SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK,
     57             ServiceWorkerResponse());
     58 }
     59 
     60 void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
     61   TRACE_EVENT_ASYNC_BEGIN0(
     62       "ServiceWorker",
     63       "ServiceWorkerFetchDispatcher::DispatchFetchEvent",
     64       request_.get());
     65   version_->DispatchFetchEvent(
     66       *request_.get(),
     67       base::Bind(&ServiceWorkerFetchDispatcher::DidPrepare,
     68                  weak_factory_.GetWeakPtr()),
     69       base::Bind(&ServiceWorkerFetchDispatcher::DidFinish,
     70                  weak_factory_.GetWeakPtr()));
     71 }
     72 
     73 void ServiceWorkerFetchDispatcher::DidPrepare() {
     74   DCHECK(!prepare_callback_.is_null());
     75   base::Closure prepare_callback = prepare_callback_;
     76   prepare_callback.Run();
     77 }
     78 
     79 void ServiceWorkerFetchDispatcher::DidFinish(
     80     ServiceWorkerStatusCode status,
     81     ServiceWorkerFetchEventResult fetch_result,
     82     const ServiceWorkerResponse& response) {
     83   TRACE_EVENT_ASYNC_END0(
     84       "ServiceWorker",
     85       "ServiceWorkerFetchDispatcher::DispatchFetchEvent",
     86       request_.get());
     87   DCHECK(!fetch_callback_.is_null());
     88   FetchCallback fetch_callback = fetch_callback_;
     89   fetch_callback.Run(status, fetch_result, response);
     90 }
     91 
     92 }  // namespace content
     93