Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_provider_host.cc
index fbfb61d..2da7d3e 100644 (file)
 #include "content/browser/service_worker/service_worker_provider_host.h"
 
 #include "base/stl_util.h"
+#include "content/browser/message_port_message_filter.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_context_request_handler.h"
+#include "content/browser/service_worker/service_worker_controllee_request_handler.h"
+#include "content/browser/service_worker/service_worker_dispatcher_host.h"
+#include "content/browser/service_worker/service_worker_handle.h"
 #include "content/browser/service_worker/service_worker_utils.h"
 #include "content/browser/service_worker/service_worker_version.h"
+#include "content/common/service_worker/service_worker_messages.h"
 
 namespace content {
 
+static const int kDocumentMainThreadId = 0;
+
 ServiceWorkerProviderHost::ServiceWorkerProviderHost(
-    int process_id, int provider_id)
+    int process_id, int provider_id,
+    base::WeakPtr<ServiceWorkerContextCore> context,
+    ServiceWorkerDispatcherHost* dispatcher_host)
     : process_id_(process_id),
-      provider_id_(provider_id) {
+      provider_id_(provider_id),
+      context_(context),
+      dispatcher_host_(dispatcher_host) {
 }
 
 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
-  AssociateVersion(NULL);
+  if (active_version_)
+    active_version_->RemoveControllee(this);
+  if (pending_version_)
+    pending_version_->RemovePendingControllee(this);
 }
 
-void ServiceWorkerProviderHost::AssociateVersion(
+void ServiceWorkerProviderHost::SetActiveVersion(
     ServiceWorkerVersion* version) {
-  if (associated_version())
-    associated_version_->RemoveProcessToWorker(process_id_);
-  associated_version_ = version;
+  if (version == active_version_)
+    return;
+  scoped_refptr<ServiceWorkerVersion> previous_version = active_version_;
+  active_version_ = version;
   if (version)
-    version->AddProcessToWorker(process_id_);
+    version->AddControllee(this);
+  if (previous_version)
+    previous_version->RemoveControllee(this);
+
+  if (!dispatcher_host_)
+    return;  // Could be NULL in some tests.
+
+  ServiceWorkerObjectInfo info;
+  if (context_ && version) {
+    scoped_ptr<ServiceWorkerHandle> handle =
+        ServiceWorkerHandle::Create(context_, dispatcher_host_,
+                                    kDocumentMainThreadId, version);
+    info = handle->GetObjectInfo();
+    dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass());
+  }
+  dispatcher_host_->Send(
+      new ServiceWorkerMsg_SetCurrentServiceWorker(
+          kDocumentMainThreadId, provider_id(), info));
 }
 
-void ServiceWorkerProviderHost::AddScriptClient(int thread_id) {
-  DCHECK(!ContainsKey(script_client_thread_ids_, thread_id));
-  script_client_thread_ids_.insert(thread_id);
+void ServiceWorkerProviderHost::SetPendingVersion(
+    ServiceWorkerVersion* version) {
+  if (version == pending_version_)
+    return;
+  scoped_refptr<ServiceWorkerVersion> previous_version = pending_version_;
+  pending_version_ = version;
+  if (version)
+    version->AddPendingControllee(this);
+  if (previous_version)
+    previous_version->RemovePendingControllee(this);
+
+  if (!dispatcher_host_)
+    return;  // Could be NULL in some tests.
+
+  // TODO(kinuko): dispatch pendingchange event to the document.
 }
 
-void ServiceWorkerProviderHost::RemoveScriptClient(int thread_id) {
-  DCHECK(ContainsKey(script_client_thread_ids_, thread_id));
-  script_client_thread_ids_.erase(thread_id);
+bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) {
+  if (!context_)
+    return true;  // System is shutting down.
+  if (active_version_)
+    return false;  // Unexpected bad message.
+
+  ServiceWorkerVersion* live_version = context_->GetLiveVersion(version_id);
+  if (!live_version)
+    return true;  // Was deleted before it got started.
+
+  ServiceWorkerVersionInfo info = live_version->GetInfo();
+  if (info.running_status != ServiceWorkerVersion::STARTING ||
+      info.process_id != process_id_) {
+    // If we aren't trying to start this version in our process
+    // something is amiss.
+    return false;
+  }
+
+  running_hosted_version_ = live_version;
+  return true;
 }
 
-bool ServiceWorkerProviderHost::ShouldHandleRequest(
-    ResourceType::Type resource_type) const {
-  if (ServiceWorkerUtils::IsMainResourceType(resource_type))
-    return true;
+scoped_ptr<ServiceWorkerRequestHandler>
+ServiceWorkerProviderHost::CreateRequestHandler(
+    ResourceType::Type resource_type) {
+  if (IsHostToRunningServiceWorker()) {
+    return scoped_ptr<ServiceWorkerRequestHandler>(
+        new ServiceWorkerContextRequestHandler(
+            context_, AsWeakPtr(), resource_type));
+  }
+  if (ServiceWorkerUtils::IsMainResourceType(resource_type) ||
+      active_version()) {
+    return scoped_ptr<ServiceWorkerRequestHandler>(
+        new ServiceWorkerControlleeRequestHandler(
+            context_, AsWeakPtr(), resource_type));
+  }
+  return scoped_ptr<ServiceWorkerRequestHandler>();
+}
 
-  if (associated_version())
-    return true;
+void ServiceWorkerProviderHost::PostMessage(
+    const base::string16& message,
+    const std::vector<int>& sent_message_port_ids) {
+  if (!dispatcher_host_)
+    return;  // Could be NULL in some tests.
 
-  // TODO(kinuko): Handle ServiceWorker cases.
-  // For now we always return false here, so that we don't handle
-  // requests for ServiceWorker (either for the main or sub resources).
+  std::vector<int> new_routing_ids;
+  dispatcher_host_->message_port_message_filter()->
+      UpdateMessagePortsWithNewRoutes(sent_message_port_ids,
+                                      &new_routing_ids);
 
-  return false;
+  dispatcher_host_->Send(
+      new ServiceWorkerMsg_MessageToDocument(
+          kDocumentMainThreadId, provider_id(),
+          message,
+          sent_message_port_ids,
+          new_routing_ids));
 }
 
 }  // namespace content