Merge from Chromium at DEPS revision 290040

This commit was generated by merge_to_master.py.

Change-Id: I694ec52d1e0b553f163c2faf4373d63270ab1aac
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc
index 3b9bf49..255c4bf 100644
--- a/content/child/service_worker/service_worker_dispatcher.cc
+++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -10,6 +10,7 @@
 #include "content/child/child_thread.h"
 #include "content/child/service_worker/service_worker_handle_reference.h"
 #include "content/child/service_worker/service_worker_provider_context.h"
+#include "content/child/service_worker/service_worker_registration_handle_reference.h"
 #include "content/child/service_worker/web_service_worker_impl.h"
 #include "content/child/service_worker/web_service_worker_registration_impl.h"
 #include "content/child/thread_safe_sender.h"
@@ -59,12 +60,8 @@
                         OnRegistrationError)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged,
                         OnServiceWorkerStateChanged)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetInstallingServiceWorker,
-                        OnSetInstallingServiceWorker)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetWaitingServiceWorker,
-                        OnSetWaitingServiceWorker)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetActiveServiceWorker,
-                        OnSetActiveServiceWorker)
+    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetVersionAttributes,
+                        OnSetVersionAttributes)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker,
                         OnSetControllerServiceWorker)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
@@ -206,9 +203,43 @@
   return new WebServiceWorkerImpl(handle_ref.Pass(), thread_safe_sender_);
 }
 
+WebServiceWorkerRegistrationImpl*
+ServiceWorkerDispatcher::GetServiceWorkerRegistration(
+    int registration_handle_id,
+    const ServiceWorkerObjectInfo& info,
+    bool adopt_handle) {
+  if (registration_handle_id == kInvalidServiceWorkerRegistrationHandleId)
+    return NULL;
+
+  RegistrationObjectMap::iterator existing_registration =
+      registrations_.find(registration_handle_id);
+
+  if (existing_registration != registrations_.end()) {
+    if (adopt_handle) {
+      // We are instructed to adopt a handle but we already have one, so
+      // adopt and destroy a handle ref.
+      ServiceWorkerRegistrationHandleReference::Adopt(
+          registration_handle_id, info, thread_safe_sender_);
+    }
+    return existing_registration->second;
+  }
+
+  scoped_ptr<ServiceWorkerRegistrationHandleReference> handle_ref =
+      adopt_handle
+          ? ServiceWorkerRegistrationHandleReference::Adopt(
+              registration_handle_id, info, thread_safe_sender_)
+          : ServiceWorkerRegistrationHandleReference::Create(
+              registration_handle_id, info, thread_safe_sender_);
+
+  // WebServiceWorkerRegistrationImpl constructor calls
+  // AddServiceWorkerRegistration.
+  return new WebServiceWorkerRegistrationImpl(handle_ref.Pass());
+}
+
 void ServiceWorkerDispatcher::OnRegistered(
     int thread_id,
     int request_id,
+    int registration_handle_id,
     const ServiceWorkerObjectInfo& info) {
   WebServiceWorkerRegistrationCallbacks* callbacks =
       pending_callbacks_.Lookup(request_id);
@@ -218,8 +249,14 @@
 
 #ifdef DISABLE_SERVICE_WORKER_REGISTRATION
   callbacks->onSuccess(GetServiceWorker(info, true));
+  // We should adopt and destroy an unused handle ref.
+  ServiceWorkerRegistrationHandleReference::Adopt(
+      registration_handle_id, info, thread_safe_sender_);
 #else
-  callbacks->onSuccess(new WebServiceWorkerRegistrationImpl(info));
+  callbacks->onSuccess(GetServiceWorkerRegistration(
+      registration_handle_id, info, true));
+  // We should adopt and destroy an unused handle ref.
+  ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
 #endif
   pending_callbacks_.Remove(request_id);
 }
@@ -267,9 +304,33 @@
     provider->second->OnServiceWorkerStateChanged(handle_id, state);
 }
 
-void ServiceWorkerDispatcher::OnSetInstallingServiceWorker(
+void ServiceWorkerDispatcher::OnSetVersionAttributes(
     int thread_id,
     int provider_id,
+    int registration_handle_id,
+    int changed_mask,
+    const ServiceWorkerVersionAttributes& attributes) {
+  ChangedVersionAttributesMask mask(changed_mask);
+  if (mask.installing_changed()) {
+    SetInstallingServiceWorker(provider_id,
+                               registration_handle_id,
+                               attributes.installing);
+  }
+  if (mask.waiting_changed()) {
+    SetWaitingServiceWorker(provider_id,
+                            registration_handle_id,
+                            attributes.waiting);
+  }
+  if (mask.active_changed()) {
+    SetActiveServiceWorker(provider_id,
+                           registration_handle_id,
+                           attributes.active);
+  }
+}
+
+void ServiceWorkerDispatcher::SetInstallingServiceWorker(
+    int provider_id,
+    int registration_handle_id,
     const ServiceWorkerObjectInfo& info) {
   ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
   if (provider != provider_contexts_.end()) {
@@ -287,16 +348,26 @@
       worker_to_provider_[info.handle_id] = provider->second;
   }
 
+#ifdef DISABLE_SERVICE_WORKER_REGISTRATION
   ScriptClientMap::iterator found = script_clients_.find(provider_id);
   if (found != script_clients_.end()) {
     // Populate the .installing field with the new worker object.
     found->second->setInstalling(GetServiceWorker(info, false));
   }
+#else
+  RegistrationObjectMap::iterator found =
+      registrations_.find(registration_handle_id);
+  if (found != registrations_.end()) {
+    found->second->setInstalling(GetServiceWorker(info, false));
+    if (info.handle_id != kInvalidServiceWorkerHandleId)
+      found->second->OnUpdateFound();
+  }
+#endif
 }
 
-void ServiceWorkerDispatcher::OnSetWaitingServiceWorker(
-    int thread_id,
+void ServiceWorkerDispatcher::SetWaitingServiceWorker(
     int provider_id,
+    int registration_handle_id,
     const ServiceWorkerObjectInfo& info) {
   ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
   if (provider != provider_contexts_.end()) {
@@ -314,16 +385,23 @@
       worker_to_provider_[info.handle_id] = provider->second;
   }
 
+#ifdef DISABLE_SERVICE_WORKER_REGISTRATION
   ScriptClientMap::iterator found = script_clients_.find(provider_id);
   if (found != script_clients_.end()) {
     // Populate the .waiting field with the new worker object.
     found->second->setWaiting(GetServiceWorker(info, false));
   }
+#else
+  RegistrationObjectMap::iterator found =
+      registrations_.find(registration_handle_id);
+  if (found != registrations_.end())
+    found->second->setWaiting(GetServiceWorker(info, false));
+#endif
 }
 
-void ServiceWorkerDispatcher::OnSetActiveServiceWorker(
-    int thread_id,
+void ServiceWorkerDispatcher::SetActiveServiceWorker(
     int provider_id,
+    int registration_handle_id,
     const ServiceWorkerObjectInfo& info) {
   ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
   if (provider != provider_contexts_.end()) {
@@ -341,11 +419,18 @@
       worker_to_provider_[info.handle_id] = provider->second;
   }
 
+#ifdef DISABLE_SERVICE_WORKER_REGISTRATION
   ScriptClientMap::iterator found = script_clients_.find(provider_id);
   if (found != script_clients_.end()) {
     // Populate the .active field with the new worker object.
     found->second->setActive(GetServiceWorker(info, false));
   }
+#else
+  RegistrationObjectMap::iterator found =
+      registrations_.find(registration_handle_id);
+  if (found != registrations_.end())
+    found->second->setActive(GetServiceWorker(info, false));
+#endif
 }
 
 void ServiceWorkerDispatcher::OnSetControllerServiceWorker(
@@ -406,4 +491,17 @@
   service_workers_.erase(handle_id);
 }
 
+void ServiceWorkerDispatcher::AddServiceWorkerRegistration(
+    int registration_handle_id,
+    WebServiceWorkerRegistrationImpl* registration) {
+  DCHECK(!ContainsKey(registrations_, registration_handle_id));
+  registrations_[registration_handle_id] = registration;
+}
+
+void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration(
+    int registration_handle_id) {
+  DCHECK(ContainsKey(registrations_, registration_handle_id));
+  registrations_.erase(registration_handle_id);
+}
+
 }  // namespace content