Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_controllee_request_handler.cc
index bd8205b..4baa445 100644 (file)
@@ -4,12 +4,14 @@
 
 #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
 
+#include "base/debug/trace_event.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_metrics.h"
 #include "content/browser/service_worker/service_worker_provider_host.h"
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_url_request_job.h"
 #include "content/browser/service_worker/service_worker_utils.h"
+#include "content/common/resource_request_body.h"
 #include "content/common/service_worker/service_worker_types.h"
 #include "net/base/load_flags.h"
 #include "net/base/net_util.h"
@@ -20,14 +22,16 @@ namespace content {
 ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
     base::WeakPtr<ServiceWorkerContextCore> context,
     base::WeakPtr<ServiceWorkerProviderHost> provider_host,
-    base::WeakPtr<webkit_blob::BlobStorageContext> blob_storage_context,
-    ResourceType resource_type)
+    base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
+    ResourceType resource_type,
+    scoped_refptr<ResourceRequestBody> body)
     : ServiceWorkerRequestHandler(context,
                                   provider_host,
                                   blob_storage_context,
                                   resource_type),
       is_main_resource_load_(
           ServiceWorkerUtils::IsMainResourceType(resource_type)),
+      body_(body),
       weak_factory_(this) {
 }
 
@@ -41,6 +45,9 @@ ServiceWorkerControlleeRequestHandler::
     else
       provider_host_->active_version()->DeferScheduledUpdate();
   }
+
+  if (is_main_resource_load_ && provider_host_)
+    provider_host_->SetAllowAssociation(true);
 }
 
 net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
@@ -52,15 +59,6 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
     return NULL;
   }
 
-  if (request->load_flags() & net::LOAD_BYPASS_CACHE) {
-    if (is_main_resource_load_) {
-      provider_host_->SetDocumentUrl(
-          net::SimplifyUrlForRequest(request->url()));
-    }
-    job_ = NULL;
-    return NULL;
-  }
-
   // This may get called multiple times for original and redirect requests:
   // A. original request case: job_ is null, no previous location info.
   // B. redirect or restarted request case:
@@ -79,7 +77,7 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
   DCHECK(!job_.get() || job_->ShouldForwardToServiceWorker());
 
   job_ = new ServiceWorkerURLRequestJob(
-      request, network_delegate, provider_host_, blob_storage_context_);
+      request, network_delegate, provider_host_, blob_storage_context_, body_);
   if (is_main_resource_load_)
     PrepareForMainResource(request->url());
   else
@@ -98,23 +96,39 @@ net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
 
 void ServiceWorkerControlleeRequestHandler::GetExtraResponseInfo(
     bool* was_fetched_via_service_worker,
-    GURL* original_url_via_service_worker) const {
-  if (!job_) {
+    GURL* original_url_via_service_worker,
+    base::TimeTicks* fetch_start_time,
+    base::TimeTicks* fetch_ready_time,
+    base::TimeTicks* fetch_end_time) const {
+  if (!job_.get()) {
     *was_fetched_via_service_worker = false;
     *original_url_via_service_worker = GURL();
     return;
   }
   job_->GetExtraResponseInfo(was_fetched_via_service_worker,
-                             original_url_via_service_worker);
+                             original_url_via_service_worker,
+                             fetch_start_time,
+                             fetch_ready_time,
+                             fetch_end_time);
 }
 
 void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
     const GURL& url) {
   DCHECK(job_.get());
   DCHECK(context_);
+  DCHECK(provider_host_);
+  TRACE_EVENT_ASYNC_BEGIN1(
+      "ServiceWorker",
+      "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
+      job_.get(),
+      "URL", url.spec());
   // The corresponding provider_host may already have associated a registration
   // in redirect case, unassociate it now.
-  provider_host_->UnassociateRegistration();
+  provider_host_->DisassociateRegistration();
+
+  // Also prevent a registrater job for establishing an association to a new
+  // registration while we're finding an existing registration.
+  provider_host_->SetAllowAssociation(false);
 
   GURL stripped_url = net::SimplifyUrlForRequest(url);
   provider_host_->SetDocumentUrl(stripped_url);
@@ -129,13 +143,18 @@ ServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource(
     ServiceWorkerStatusCode status,
     const scoped_refptr<ServiceWorkerRegistration>& registration) {
   DCHECK(job_.get());
-  if (status != SERVICE_WORKER_OK) {
+  if (provider_host_)
+    provider_host_->SetAllowAssociation(true);
+  if (status != SERVICE_WORKER_OK || !provider_host_) {
     job_->FallbackToNetwork();
+    TRACE_EVENT_ASYNC_END1(
+        "ServiceWorker",
+        "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
+        job_.get(),
+        "Status", status);
     return;
   }
-  DCHECK(registration);
-
-  ServiceWorkerMetrics::CountControlledPageLoad();
+  DCHECK(registration.get());
 
   // Initiate activation of a waiting version.
   // Usually a register job initiates activation but that
@@ -148,35 +167,63 @@ ServiceWorkerControlleeRequestHandler::DidLookupRegistrationForMainResource(
       registration->active_version();
 
   // Wait until it's activated before firing fetch events.
-  if (active_version &&
+  if (active_version.get() &&
       active_version->status() == ServiceWorkerVersion::ACTIVATING) {
+    provider_host_->SetAllowAssociation(false);
     registration->active_version()->RegisterStatusChangeCallback(
         base::Bind(&self::OnVersionStatusChanged,
                    weak_factory_.GetWeakPtr(),
                    registration,
                    active_version));
+    TRACE_EVENT_ASYNC_END2(
+        "ServiceWorker",
+        "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
+        job_.get(),
+        "Status", status,
+        "Info", "Wait until finished SW activation");
     return;
   }
 
-  if (!active_version ||
+  if (!active_version.get() ||
       active_version->status() != ServiceWorkerVersion::ACTIVATED) {
     job_->FallbackToNetwork();
+    TRACE_EVENT_ASYNC_END2(
+        "ServiceWorker",
+        "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
+        job_.get(),
+        "Status", status,
+        "Info",
+        "ServiceWorkerVersion is not available, so falling back to network");
     return;
   }
 
-  provider_host_->AssociateRegistration(registration);
+  ServiceWorkerMetrics::CountControlledPageLoad();
+
+  provider_host_->AssociateRegistration(registration.get());
   job_->ForwardToServiceWorker();
+  TRACE_EVENT_ASYNC_END2(
+      "ServiceWorker",
+      "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
+      job_.get(),
+      "Status", status,
+      "Info",
+      "Forwarded to the ServiceWorker");
 }
 
 void ServiceWorkerControlleeRequestHandler::OnVersionStatusChanged(
     ServiceWorkerRegistration* registration,
     ServiceWorkerVersion* version) {
+  if (provider_host_)
+    provider_host_->SetAllowAssociation(true);
   if (version != registration->active_version() ||
-      version->status() != ServiceWorkerVersion::ACTIVATED) {
+      version->status() != ServiceWorkerVersion::ACTIVATED ||
+      !provider_host_) {
     job_->FallbackToNetwork();
     return;
   }
 
+  ServiceWorkerMetrics::CountControlledPageLoad();
+
   provider_host_->AssociateRegistration(registration);
   job_->ForwardToServiceWorker();
 }