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 11namespace content { 12 13ServiceWorkerFetchDispatcher::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 25ServiceWorkerFetchDispatcher::~ServiceWorkerFetchDispatcher() {} 26 27void 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 41void ServiceWorkerFetchDispatcher::DidWaitActivation() { 42 if (version_->status() != ServiceWorkerVersion::ACTIVATED) { 43 DCHECK_EQ(ServiceWorkerVersion::INSTALLED, version_->status()); 44 DidFailActivation(); 45 return; 46 } 47 DispatchFetchEvent(); 48} 49 50void 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 60void 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 73void ServiceWorkerFetchDispatcher::DidPrepare() { 74 DCHECK(!prepare_callback_.is_null()); 75 base::Closure prepare_callback = prepare_callback_; 76 prepare_callback.Run(); 77} 78 79void 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