[safe_browsing] Remove unused ContainsBrowseUrl() parameter.
[chromium-blink-merge.git] / content / child / service_worker / service_worker_dispatcher.cc
blobd8ac46e89ebbaa8cbbbcbb1f53b10fea2e09062d
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.
5 #include "content/child/service_worker/service_worker_dispatcher.h"
7 #include "base/lazy_instance.h"
8 #include "base/stl_util.h"
9 #include "base/threading/thread_local.h"
10 #include "content/child/service_worker/web_service_worker_impl.h"
11 #include "content/child/thread_safe_sender.h"
12 #include "content/common/service_worker/service_worker_messages.h"
13 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
15 using blink::WebServiceWorkerError;
16 using blink::WebServiceWorkerProvider;
17 using base::ThreadLocalPointer;
19 namespace content {
21 namespace {
23 base::LazyInstance<ThreadLocalPointer<ServiceWorkerDispatcher> >::Leaky
24 g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER;
26 ServiceWorkerDispatcher* const kHasBeenDeleted =
27 reinterpret_cast<ServiceWorkerDispatcher*>(0x1);
29 int CurrentWorkerId() {
30 return WorkerTaskRunner::Instance()->CurrentWorkerId();
33 } // namespace
35 ServiceWorkerDispatcher::ServiceWorkerDispatcher(
36 ThreadSafeSender* thread_safe_sender)
37 : thread_safe_sender_(thread_safe_sender) {
38 g_dispatcher_tls.Pointer()->Set(this);
41 ServiceWorkerDispatcher::~ServiceWorkerDispatcher() {
42 for (ScriptClientMap::iterator it = script_clients_.begin();
43 it != script_clients_.end();
44 ++it) {
45 Send(new ServiceWorkerHostMsg_RemoveScriptClient(
46 CurrentWorkerId(), it->first));
49 g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted);
52 void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) {
53 bool handled = true;
54 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg)
55 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered, OnRegistered)
56 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered,
57 OnUnregistered)
58 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistrationError,
59 OnRegistrationError)
60 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerStateChanged,
61 OnServiceWorkerStateChanged)
62 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_SetCurrentServiceWorker,
63 OnSetCurrentServiceWorker)
64 IPC_MESSAGE_UNHANDLED(handled = false)
65 IPC_END_MESSAGE_MAP()
66 DCHECK(handled) << "Unhandled message:" << msg.type();
69 bool ServiceWorkerDispatcher::Send(IPC::Message* msg) {
70 return thread_safe_sender_->Send(msg);
73 void ServiceWorkerDispatcher::RegisterServiceWorker(
74 int provider_id,
75 const GURL& pattern,
76 const GURL& script_url,
77 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks) {
78 DCHECK(callbacks);
79 int request_id = pending_callbacks_.Add(callbacks);
80 thread_safe_sender_->Send(new ServiceWorkerHostMsg_RegisterServiceWorker(
81 CurrentWorkerId(), request_id, provider_id, pattern, script_url));
84 void ServiceWorkerDispatcher::UnregisterServiceWorker(
85 int provider_id,
86 const GURL& pattern,
87 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks) {
88 DCHECK(callbacks);
89 int request_id = pending_callbacks_.Add(callbacks);
90 thread_safe_sender_->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker(
91 CurrentWorkerId(), request_id, provider_id, pattern));
94 void ServiceWorkerDispatcher::AddScriptClient(
95 int provider_id,
96 blink::WebServiceWorkerProviderClient* client) {
97 DCHECK(client);
98 DCHECK(!ContainsKey(script_clients_, provider_id));
99 script_clients_[provider_id] = client;
100 thread_safe_sender_->Send(new ServiceWorkerHostMsg_AddScriptClient(
101 CurrentWorkerId(), provider_id));
104 void ServiceWorkerDispatcher::RemoveScriptClient(int provider_id) {
105 // This could be possibly called multiple times to ensure termination.
106 if (ContainsKey(script_clients_, provider_id)) {
107 script_clients_.erase(provider_id);
108 thread_safe_sender_->Send(new ServiceWorkerHostMsg_RemoveScriptClient(
109 CurrentWorkerId(), provider_id));
113 ServiceWorkerDispatcher*
114 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
115 ThreadSafeSender* thread_safe_sender) {
116 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) {
117 NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher.";
118 g_dispatcher_tls.Pointer()->Set(NULL);
120 if (g_dispatcher_tls.Pointer()->Get())
121 return g_dispatcher_tls.Pointer()->Get();
123 ServiceWorkerDispatcher* dispatcher =
124 new ServiceWorkerDispatcher(thread_safe_sender);
125 if (WorkerTaskRunner::Instance()->CurrentWorkerId())
126 WorkerTaskRunner::Instance()->AddStopObserver(dispatcher);
127 return dispatcher;
130 ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() {
131 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted)
132 return NULL;
133 return g_dispatcher_tls.Pointer()->Get();
136 void ServiceWorkerDispatcher::OnWorkerRunLoopStopped() {
137 delete this;
140 void ServiceWorkerDispatcher::OnRegistered(
141 int thread_id,
142 int request_id,
143 const ServiceWorkerObjectInfo& info) {
144 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks =
145 pending_callbacks_.Lookup(request_id);
146 DCHECK(callbacks);
147 if (!callbacks)
148 return;
150 // The browser has to generate the registration_id so the same
151 // worker can be called from different renderer contexts. However,
152 // the impl object doesn't have to be the same instance across calls
153 // unless we require the DOM objects to be identical when there's a
154 // duplicate registration. So for now we mint a new object each
155 // time.
157 // WebServiceWorkerImpl's ctor internally calls AddServiceWorker.
158 scoped_ptr<WebServiceWorkerImpl> worker(
159 new WebServiceWorkerImpl(info, thread_safe_sender_));
160 callbacks->onSuccess(worker.release());
161 pending_callbacks_.Remove(request_id);
164 void ServiceWorkerDispatcher::OnUnregistered(
165 int thread_id,
166 int request_id) {
167 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks =
168 pending_callbacks_.Lookup(request_id);
169 DCHECK(callbacks);
170 if (!callbacks)
171 return;
173 callbacks->onSuccess(NULL);
174 pending_callbacks_.Remove(request_id);
177 void ServiceWorkerDispatcher::OnRegistrationError(
178 int thread_id,
179 int request_id,
180 WebServiceWorkerError::ErrorType error_type,
181 const base::string16& message) {
182 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks =
183 pending_callbacks_.Lookup(request_id);
184 DCHECK(callbacks);
185 if (!callbacks)
186 return;
188 scoped_ptr<WebServiceWorkerError> error(
189 new WebServiceWorkerError(error_type, message));
190 callbacks->onError(error.release());
191 pending_callbacks_.Remove(request_id);
194 void ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
195 int thread_id,
196 int handle_id,
197 blink::WebServiceWorkerState state) {
198 ServiceWorkerMap::iterator found = service_workers_.find(handle_id);
199 if (found == service_workers_.end())
200 return;
201 found->second->OnStateChanged(state);
204 void ServiceWorkerDispatcher::OnSetCurrentServiceWorker(
205 int thread_id,
206 int provider_id,
207 const ServiceWorkerObjectInfo& info) {
208 scoped_ptr<WebServiceWorkerImpl> worker(
209 new WebServiceWorkerImpl(info, thread_safe_sender_));
210 ScriptClientMap::iterator found = script_clients_.find(provider_id);
211 if (found == script_clients_.end()) {
212 // Note that |worker|'s destructor sends a ServiceWorkerObjectDestroyed
213 // message so the browser-side can clean up the ServiceWorkerHandle it
214 // created when sending us this message.
215 return;
217 // TODO(falken): Call client->setCurrentServiceWorker(worker) when the Blink
218 // change to add that function rolls in.
221 void ServiceWorkerDispatcher::AddServiceWorker(
222 int handle_id, WebServiceWorkerImpl* worker) {
223 DCHECK(!ContainsKey(service_workers_, handle_id));
224 service_workers_[handle_id] = worker;
227 void ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id) {
228 DCHECK(ContainsKey(service_workers_, handle_id));
229 service_workers_.erase(handle_id);
232 } // namespace content