Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_provider_host.cc
1 // Copyright 2013 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_provider_host.h"
6
7 #include "base/stl_util.h"
8 #include "content/browser/message_port_message_filter.h"
9 #include "content/browser/service_worker/service_worker_context_core.h"
10 #include "content/browser/service_worker/service_worker_context_request_handler.h"
11 #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
12 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
13 #include "content/browser/service_worker/service_worker_handle.h"
14 #include "content/browser/service_worker/service_worker_utils.h"
15 #include "content/browser/service_worker/service_worker_version.h"
16 #include "content/common/service_worker/service_worker_messages.h"
17
18 namespace content {
19
20 static const int kDocumentMainThreadId = 0;
21
22 ServiceWorkerProviderHost::ServiceWorkerProviderHost(
23     int process_id, int provider_id,
24     base::WeakPtr<ServiceWorkerContextCore> context,
25     ServiceWorkerDispatcherHost* dispatcher_host)
26     : process_id_(process_id),
27       provider_id_(provider_id),
28       context_(context),
29       dispatcher_host_(dispatcher_host) {
30 }
31
32 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
33   if (active_version_)
34     active_version_->RemoveControllee(this);
35   if (pending_version_)
36     pending_version_->RemovePendingControllee(this);
37 }
38
39 void ServiceWorkerProviderHost::SetActiveVersion(
40     ServiceWorkerVersion* version) {
41   if (version == active_version_)
42     return;
43   scoped_refptr<ServiceWorkerVersion> previous_version = active_version_;
44   active_version_ = version;
45   if (version)
46     version->AddControllee(this);
47   if (previous_version)
48     previous_version->RemoveControllee(this);
49
50   if (!dispatcher_host_)
51     return;  // Could be NULL in some tests.
52
53   ServiceWorkerObjectInfo info;
54   if (context_ && version) {
55     scoped_ptr<ServiceWorkerHandle> handle =
56         ServiceWorkerHandle::Create(context_, dispatcher_host_,
57                                     kDocumentMainThreadId, version);
58     info = handle->GetObjectInfo();
59     dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass());
60   }
61   dispatcher_host_->Send(
62       new ServiceWorkerMsg_SetCurrentServiceWorker(
63           kDocumentMainThreadId, provider_id(), info));
64 }
65
66 void ServiceWorkerProviderHost::SetPendingVersion(
67     ServiceWorkerVersion* version) {
68   if (version == pending_version_)
69     return;
70   scoped_refptr<ServiceWorkerVersion> previous_version = pending_version_;
71   pending_version_ = version;
72   if (version)
73     version->AddPendingControllee(this);
74   if (previous_version)
75     previous_version->RemovePendingControllee(this);
76
77   if (!dispatcher_host_)
78     return;  // Could be NULL in some tests.
79
80   // TODO(kinuko): dispatch pendingchange event to the document.
81 }
82
83 bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) {
84   if (!context_)
85     return true;  // System is shutting down.
86   if (active_version_)
87     return false;  // Unexpected bad message.
88
89   ServiceWorkerVersion* live_version = context_->GetLiveVersion(version_id);
90   if (!live_version)
91     return true;  // Was deleted before it got started.
92
93   ServiceWorkerVersionInfo info = live_version->GetInfo();
94   if (info.running_status != ServiceWorkerVersion::STARTING ||
95       info.process_id != process_id_) {
96     // If we aren't trying to start this version in our process
97     // something is amiss.
98     return false;
99   }
100
101   running_hosted_version_ = live_version;
102   return true;
103 }
104
105 scoped_ptr<ServiceWorkerRequestHandler>
106 ServiceWorkerProviderHost::CreateRequestHandler(
107     ResourceType::Type resource_type) {
108   if (IsHostToRunningServiceWorker()) {
109     return scoped_ptr<ServiceWorkerRequestHandler>(
110         new ServiceWorkerContextRequestHandler(
111             context_, AsWeakPtr(), resource_type));
112   }
113   if (ServiceWorkerUtils::IsMainResourceType(resource_type) ||
114       active_version()) {
115     return scoped_ptr<ServiceWorkerRequestHandler>(
116         new ServiceWorkerControlleeRequestHandler(
117             context_, AsWeakPtr(), resource_type));
118   }
119   return scoped_ptr<ServiceWorkerRequestHandler>();
120 }
121
122 void ServiceWorkerProviderHost::PostMessage(
123     const base::string16& message,
124     const std::vector<int>& sent_message_port_ids) {
125   if (!dispatcher_host_)
126     return;  // Could be NULL in some tests.
127
128   std::vector<int> new_routing_ids;
129   dispatcher_host_->message_port_message_filter()->
130       UpdateMessagePortsWithNewRoutes(sent_message_port_ids,
131                                       &new_routing_ids);
132
133   dispatcher_host_->Send(
134       new ServiceWorkerMsg_MessageToDocument(
135           kDocumentMainThreadId, provider_id(),
136           message,
137           sent_message_port_ids,
138           new_routing_ids));
139 }
140
141 }  // namespace content