Merge from Chromium at DEPS revision 284076

This commit was generated by merge_to_master.py.

Change-Id: I9a279485b02fe7ceddcd32d992a714ff132e99ae
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc
index 936f5c8..81f2c4e 100644
--- a/content/child/service_worker/service_worker_dispatcher.cc
+++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -58,10 +58,14 @@
                         OnRegistrationError)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged,
                         OnServiceWorkerStateChanged)
+    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetInstallingServiceWorker,
+                        OnSetInstallingServiceWorker)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetWaitingServiceWorker,
                         OnSetWaitingServiceWorker)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetCurrentServiceWorker,
-                        OnSetCurrentServiceWorker)
+    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetActiveServiceWorker,
+                        OnSetActiveServiceWorker)
+    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker,
+                        OnSetControllerServiceWorker)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_MessageToDocument,
                         OnPostMessage)
     IPC_MESSAGE_UNHANDLED(handled = false)
@@ -128,8 +132,10 @@
   DCHECK(provider_context);
   DCHECK(ContainsKey(provider_contexts_, provider_context->provider_id()));
   provider_contexts_.erase(provider_context->provider_id());
+  worker_to_provider_.erase(provider_context->installing_handle_id());
   worker_to_provider_.erase(provider_context->waiting_handle_id());
-  worker_to_provider_.erase(provider_context->current_handle_id());
+  worker_to_provider_.erase(provider_context->active_handle_id());
+  worker_to_provider_.erase(provider_context->controller_handle_id());
 }
 
 void ServiceWorkerDispatcher::AddScriptClient(
@@ -256,6 +262,33 @@
     provider->second->OnServiceWorkerStateChanged(handle_id, state);
 }
 
+void ServiceWorkerDispatcher::OnSetInstallingServiceWorker(
+    int thread_id,
+    int provider_id,
+    const ServiceWorkerObjectInfo& info) {
+  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
+  if (provider != provider_contexts_.end()) {
+    int existing_installing_id = provider->second->installing_handle_id();
+    if (existing_installing_id != info.handle_id &&
+        existing_installing_id != kInvalidServiceWorkerHandleId) {
+      WorkerToProviderMap::iterator associated_provider =
+          worker_to_provider_.find(existing_installing_id);
+      DCHECK(associated_provider != worker_to_provider_.end());
+      DCHECK(associated_provider->second->provider_id() == provider_id);
+      worker_to_provider_.erase(associated_provider);
+    }
+    provider->second->OnSetInstallingServiceWorker(provider_id, info);
+    if (info.handle_id != kInvalidServiceWorkerHandleId)
+      worker_to_provider_[info.handle_id] = provider->second;
+  }
+
+  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));
+  }
+}
+
 void ServiceWorkerDispatcher::OnSetWaitingServiceWorker(
     int thread_id,
     int provider_id,
@@ -283,13 +316,40 @@
   }
 }
 
-void ServiceWorkerDispatcher::OnSetCurrentServiceWorker(
+void ServiceWorkerDispatcher::OnSetActiveServiceWorker(
     int thread_id,
     int provider_id,
     const ServiceWorkerObjectInfo& info) {
   ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
   if (provider != provider_contexts_.end()) {
-    provider->second->OnSetCurrentServiceWorker(provider_id, info);
+    int existing_active_id = provider->second->active_handle_id();
+    if (existing_active_id != info.handle_id &&
+        existing_active_id != kInvalidServiceWorkerHandleId) {
+      WorkerToProviderMap::iterator associated_provider =
+          worker_to_provider_.find(existing_active_id);
+      DCHECK(associated_provider != worker_to_provider_.end());
+      DCHECK(associated_provider->second->provider_id() == provider_id);
+      worker_to_provider_.erase(associated_provider);
+    }
+    provider->second->OnSetActiveServiceWorker(provider_id, info);
+    if (info.handle_id != kInvalidServiceWorkerHandleId)
+      worker_to_provider_[info.handle_id] = provider->second;
+  }
+
+  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));
+  }
+}
+
+void ServiceWorkerDispatcher::OnSetControllerServiceWorker(
+    int thread_id,
+    int provider_id,
+    const ServiceWorkerObjectInfo& info) {
+  ProviderContextMap::iterator provider = provider_contexts_.find(provider_id);
+  if (provider != provider_contexts_.end()) {
+    provider->second->OnSetControllerServiceWorker(provider_id, info);
     worker_to_provider_[info.handle_id] = provider->second;
   }
 
diff --git a/content/child/service_worker/service_worker_dispatcher.h b/content/child/service_worker/service_worker_dispatcher.h
index 84ea387..573e68e 100644
--- a/content/child/service_worker/service_worker_dispatcher.h
+++ b/content/child/service_worker/service_worker_dispatcher.h
@@ -120,12 +120,18 @@
   void OnServiceWorkerStateChanged(int thread_id,
                                    int handle_id,
                                    blink::WebServiceWorkerState state);
+  void OnSetInstallingServiceWorker(int thread_id,
+                                    int provider_id,
+                                    const ServiceWorkerObjectInfo& info);
   void OnSetWaitingServiceWorker(int thread_id,
                                  int provider_id,
                                  const ServiceWorkerObjectInfo& info);
-  void OnSetCurrentServiceWorker(int thread_id,
-                                 int provider_id,
-                                 const ServiceWorkerObjectInfo& info);
+  void OnSetActiveServiceWorker(int thread_id,
+                                int provider_id,
+                                const ServiceWorkerObjectInfo& info);
+  void OnSetControllerServiceWorker(int thread_id,
+                                    int provider_id,
+                                    const ServiceWorkerObjectInfo& info);
   void OnPostMessage(int thread_id,
                      int provider_id,
                      const base::string16& message,
diff --git a/content/child/service_worker/service_worker_message_filter.cc b/content/child/service_worker/service_worker_message_filter.cc
index 71632f7..2b95d85 100644
--- a/content/child/service_worker/service_worker_message_filter.cc
+++ b/content/child/service_worker/service_worker_message_filter.cc
@@ -63,7 +63,7 @@
                         OnStaleRegistered)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetWaitingServiceWorker,
                         OnStaleSetServiceWorker)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetCurrentServiceWorker,
+    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetControllerServiceWorker,
                         OnStaleSetServiceWorker)
   IPC_END_MESSAGE_MAP()
 }
diff --git a/content/child/service_worker/service_worker_provider_context.cc b/content/child/service_worker/service_worker_provider_context.cc
index 246a19c..222a861 100644
--- a/content/child/service_worker/service_worker_provider_context.cc
+++ b/content/child/service_worker/service_worker_provider_context.cc
@@ -36,25 +36,38 @@
   }
 }
 
+ServiceWorkerHandleReference* ServiceWorkerProviderContext::installing() {
+  DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
+  return installing_.get();
+}
+
 ServiceWorkerHandleReference* ServiceWorkerProviderContext::waiting() {
   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
   return waiting_.get();
 }
 
-ServiceWorkerHandleReference* ServiceWorkerProviderContext::current() {
+ServiceWorkerHandleReference* ServiceWorkerProviderContext::active() {
   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
-  return current_.get();
+  return active_.get();
+}
+
+ServiceWorkerHandleReference* ServiceWorkerProviderContext::controller() {
+  DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
+  return controller_.get();
 }
 
 void ServiceWorkerProviderContext::OnServiceWorkerStateChanged(
     int handle_id,
     blink::WebServiceWorkerState state) {
   ServiceWorkerHandleReference* which = NULL;
-  if (handle_id == current_handle_id()) {
-    which = current_.get();
-  } else if (handle_id == waiting_handle_id()) {
+  if (handle_id == controller_handle_id())
+    which = controller_.get();
+  else if (handle_id == active_handle_id())
+    which = active_.get();
+  else if (handle_id == waiting_handle_id())
     which = waiting_.get();
-  }
+  else if (handle_id == installing_handle_id())
+    which = installing_.get();
 
   // We should only get messages for ServiceWorkers associated with
   // this provider.
@@ -66,6 +79,13 @@
   // when we support navigator.serviceWorker in dedicated workers.
 }
 
+void ServiceWorkerProviderContext::OnSetInstallingServiceWorker(
+    int provider_id,
+    const ServiceWorkerObjectInfo& info) {
+  DCHECK_EQ(provider_id_, provider_id);
+  installing_ = ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
+}
+
 void ServiceWorkerProviderContext::OnSetWaitingServiceWorker(
     int provider_id,
     const ServiceWorkerObjectInfo& info) {
@@ -73,27 +93,48 @@
   waiting_ = ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
 }
 
-void ServiceWorkerProviderContext::OnSetCurrentServiceWorker(
+void ServiceWorkerProviderContext::OnSetActiveServiceWorker(
+    int provider_id,
+    const ServiceWorkerObjectInfo& info) {
+  DCHECK_EQ(provider_id_, provider_id);
+  active_ = ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
+}
+
+void ServiceWorkerProviderContext::OnSetControllerServiceWorker(
     int provider_id,
     const ServiceWorkerObjectInfo& info) {
   DCHECK_EQ(provider_id_, provider_id);
 
   // This context is is the primary owner of this handle, keeps the
   // initial reference until it goes away.
-  current_ = ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
+  controller_ = ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_);
 
   // TODO(kinuko): We can forward the message to other threads here
   // when we support navigator.serviceWorker in dedicated workers.
 }
 
-int ServiceWorkerProviderContext::current_handle_id() const {
+int ServiceWorkerProviderContext::installing_handle_id() const {
   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
-  return current_ ? current_->info().handle_id : kInvalidServiceWorkerHandleId;
+  return installing_ ? installing_->info().handle_id
+                     : kInvalidServiceWorkerHandleId;
 }
 
 int ServiceWorkerProviderContext::waiting_handle_id() const {
   DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
-  return waiting_ ? waiting_->info().handle_id : kInvalidServiceWorkerHandleId;
+  return waiting_ ? waiting_->info().handle_id
+                  : kInvalidServiceWorkerHandleId;
+}
+
+int ServiceWorkerProviderContext::active_handle_id() const {
+  DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
+  return active_ ? active_->info().handle_id
+                 : kInvalidServiceWorkerHandleId;
+}
+
+int ServiceWorkerProviderContext::controller_handle_id() const {
+  DCHECK(main_thread_loop_proxy_->RunsTasksOnCurrentThread());
+  return controller_ ? controller_->info().handle_id
+                     : kInvalidServiceWorkerHandleId;
 }
 
 }  // namespace content
diff --git a/content/child/service_worker/service_worker_provider_context.h b/content/child/service_worker/service_worker_provider_context.h
index 5fe68ae..ee294d9 100644
--- a/content/child/service_worker/service_worker_provider_context.h
+++ b/content/child/service_worker/service_worker_provider_context.h
@@ -28,9 +28,9 @@
 class ThreadSafeSender;
 
 // An instance of this class holds document-related information (e.g.
-// .current). Created and destructed on the main thread.
+// .controller). Created and destructed on the main thread.
 // TODO(kinuko): To support navigator.serviceWorker in dedicated workers
-// this needs to be RefCountedThreadSafe and .current info needs to be
+// this needs to be RefCountedThreadSafe and .controller info needs to be
 // handled in a thread-safe manner (e.g. by a lock etc).
 class ServiceWorkerProviderContext
     : public base::RefCounted<ServiceWorkerProviderContext> {
@@ -40,28 +40,42 @@
   // Called from ServiceWorkerDispatcher.
   void OnServiceWorkerStateChanged(int handle_id,
                                    blink::WebServiceWorkerState state);
+  void OnSetInstallingServiceWorker(int provider_id,
+                                    const ServiceWorkerObjectInfo& info);
   void OnSetWaitingServiceWorker(int provider_id,
                                  const ServiceWorkerObjectInfo& info);
-  void OnSetCurrentServiceWorker(int provider_id,
-                                 const ServiceWorkerObjectInfo& info);
+  void OnSetActiveServiceWorker(int provider_id,
+                                const ServiceWorkerObjectInfo& info);
+  void OnSetControllerServiceWorker(int provider_id,
+                                    const ServiceWorkerObjectInfo& info);
 
   int provider_id() const { return provider_id_; }
 
+  ServiceWorkerHandleReference* installing();
   ServiceWorkerHandleReference* waiting();
-  // Gets the context's handle reference for .controller.
-  // TODO(dominicc): Rename this to "controller".
-  ServiceWorkerHandleReference* current();
+  ServiceWorkerHandleReference* active();
+  ServiceWorkerHandleReference* controller();
 
-  // Gets the handle ID of the controller, or
-  // kInvalidServiceWorkerHandleId if the provider is not controlled
-  // by a Service Worker.
-  int current_handle_id() const;
+  // Gets the handle ID of the installing Service Worker, or
+  // kInvalidServiceWorkerHandleId if the provider does not have a
+  // installing Service Worker.
+  int installing_handle_id() const;
 
   // Gets the handle ID of the waiting Service Worker, or
   // kInvalidServiceWorkerHandleId if the provider does not have a
   // waiting Service Worker.
   int waiting_handle_id() const;
 
+  // Gets the handle ID of the active Service Worker, or
+  // kInvalidServiceWorkerHandleId if the provider does not have an active
+  // Service Worker.
+  int active_handle_id() const;
+
+  // Gets the handle ID of the controller Service Worker, or
+  // kInvalidServiceWorkerHandleId if the provider is not controlled
+  // by a Service Worker.
+  int controller_handle_id() const;
+
  private:
   friend class base::RefCounted<ServiceWorkerProviderContext>;
   ~ServiceWorkerProviderContext();
@@ -69,8 +83,10 @@
   const int provider_id_;
   scoped_refptr<base::MessageLoopProxy> main_thread_loop_proxy_;
   scoped_refptr<ThreadSafeSender> thread_safe_sender_;
+  scoped_ptr<ServiceWorkerHandleReference> installing_;
   scoped_ptr<ServiceWorkerHandleReference> waiting_;
-  scoped_ptr<ServiceWorkerHandleReference> current_;
+  scoped_ptr<ServiceWorkerHandleReference> active_;
+  scoped_ptr<ServiceWorkerHandleReference> controller_;
 
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContext);
 };
diff --git a/content/child/service_worker/web_service_worker_impl.cc b/content/child/service_worker/web_service_worker_impl.cc
index 685c68c..e768223 100644
--- a/content/child/service_worker/web_service_worker_impl.cc
+++ b/content/child/service_worker/web_service_worker_impl.cc
@@ -45,7 +45,7 @@
     blink::WebServiceWorkerState new_state) {
   DCHECK(proxy_);
   if (proxy_->isReady())
-    ChangeState(new_state);
+    CommitState(new_state);
   else
     queued_states_.push_back(new_state);
 }
@@ -65,7 +65,7 @@
            queued_states_.begin();
        it != queued_states_.end();
        ++it) {
-    ChangeState(*it);
+    CommitState(*it);
   }
   queued_states_.clear();
 }
@@ -90,7 +90,7 @@
       WebMessagePortChannelImpl::ExtractMessagePortIDs(channels)));
 }
 
-void WebServiceWorkerImpl::ChangeState(blink::WebServiceWorkerState new_state) {
+void WebServiceWorkerImpl::CommitState(blink::WebServiceWorkerState new_state) {
   DCHECK(proxy_);
   DCHECK(proxy_->isReady());
   state_ = new_state;
diff --git a/content/child/service_worker/web_service_worker_impl.h b/content/child/service_worker/web_service_worker_impl.h
index 4726040..b1ede90 100644
--- a/content/child/service_worker/web_service_worker_impl.h
+++ b/content/child/service_worker/web_service_worker_impl.h
@@ -55,7 +55,7 @@
 
  private:
   // Commits the new state internally and notifies the proxy of the change.
-  void ChangeState(blink::WebServiceWorkerState new_state);
+  void CommitState(blink::WebServiceWorkerState new_state);
 
   scoped_ptr<ServiceWorkerHandleReference> handle_ref_;
   blink::WebServiceWorkerState state_;
diff --git a/content/child/service_worker/web_service_worker_provider_impl.cc b/content/child/service_worker/web_service_worker_provider_impl.cc
index f6ed0fc..8660bb3 100644
--- a/content/child/service_worker/web_service_worker_provider_impl.cc
+++ b/content/child/service_worker/web_service_worker_provider_impl.cc
@@ -47,14 +47,24 @@
   // for more context)
   GetDispatcher()->AddScriptClient(provider_id_, client);
 
-  if (context_->waiting_handle_id() != kInvalidServiceWorkerHandleId) {
-    client->setWaiting(
-        GetDispatcher()->GetServiceWorker(context_->waiting()->info(), false));
+  if (context_->installing_handle_id() != kInvalidServiceWorkerHandleId) {
+    client->setInstalling(GetDispatcher()->GetServiceWorker(
+        context_->installing()->info(), false));
   }
 
-  if (context_->current_handle_id() != kInvalidServiceWorkerHandleId) {
-    client->setController(
-        GetDispatcher()->GetServiceWorker(context_->current()->info(), false));
+  if (context_->waiting_handle_id() != kInvalidServiceWorkerHandleId) {
+    client->setWaiting(GetDispatcher()->GetServiceWorker(
+        context_->waiting()->info(), false));
+  }
+
+  if (context_->active_handle_id() != kInvalidServiceWorkerHandleId) {
+    client->setActive(GetDispatcher()->GetServiceWorker(
+        context_->active()->info(), false));
+  }
+
+  if (context_->controller_handle_id() != kInvalidServiceWorkerHandleId) {
+    client->setController(GetDispatcher()->GetServiceWorker(
+        context_->controller()->info(), false));
   }
 }
 
diff --git a/content/child/service_worker/web_service_worker_provider_impl.h b/content/child/service_worker/web_service_worker_provider_impl.h
index 912d2f4..a0749d2 100644
--- a/content/child/service_worker/web_service_worker_provider_impl.h
+++ b/content/child/service_worker/web_service_worker_provider_impl.h
@@ -41,6 +41,8 @@
 
   ServiceWorkerProviderContext* context() { return context_.get(); }
 
+  int provider_id() const { return provider_id_; }
+
  private:
   void RemoveScriptClient();
   ServiceWorkerDispatcher* GetDispatcher();