| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/child/service_worker/service_worker_dispatcher.h" | 5 #include "content/child/service_worker/service_worker_dispatcher.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 using blink::WebServiceWorkerProvider; | 33 using blink::WebServiceWorkerProvider; |
| 34 using base::ThreadLocalPointer; | 34 using base::ThreadLocalPointer; |
| 35 | 35 |
| 36 namespace content { | 36 namespace content { |
| 37 | 37 |
| 38 namespace { | 38 namespace { |
| 39 | 39 |
| 40 base::LazyInstance<ThreadLocalPointer<void>>::Leaky g_dispatcher_tls = | 40 base::LazyInstance<ThreadLocalPointer<void>>::Leaky g_dispatcher_tls = |
| 41 LAZY_INSTANCE_INITIALIZER; | 41 LAZY_INSTANCE_INITIALIZER; |
| 42 | 42 |
| 43 void* const kHasBeenDeleted = reinterpret_cast<void*>(0x1); | 43 void* const kSWDispatcherHasBeenDeleted = reinterpret_cast<void*>(0x1); |
| 44 | 44 |
| 45 int CurrentWorkerId() { | 45 int ServiceWorkerCurrentWorkerId() { |
| 46 return WorkerThread::GetCurrentId(); | 46 return WorkerThread::GetCurrentId(); |
| 47 } | 47 } |
| 48 | 48 |
| 49 } // namespace | 49 } // namespace |
| 50 | 50 |
| 51 ServiceWorkerDispatcher::ServiceWorkerDispatcher( | 51 ServiceWorkerDispatcher::ServiceWorkerDispatcher( |
| 52 ThreadSafeSender* thread_safe_sender, | 52 ThreadSafeSender* thread_safe_sender, |
| 53 base::SingleThreadTaskRunner* main_thread_task_runner) | 53 base::SingleThreadTaskRunner* main_thread_task_runner) |
| 54 : thread_safe_sender_(thread_safe_sender), | 54 : thread_safe_sender_(thread_safe_sender), |
| 55 main_thread_task_runner_(main_thread_task_runner) { | 55 main_thread_task_runner_(main_thread_task_runner) { |
| 56 g_dispatcher_tls.Pointer()->Set(static_cast<void*>(this)); | 56 g_dispatcher_tls.Pointer()->Set(static_cast<void*>(this)); |
| 57 } | 57 } |
| 58 | 58 |
| 59 ServiceWorkerDispatcher::~ServiceWorkerDispatcher() { | 59 ServiceWorkerDispatcher::~ServiceWorkerDispatcher() { |
| 60 g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); | 60 g_dispatcher_tls.Pointer()->Set(kSWDispatcherHasBeenDeleted); |
| 61 } | 61 } |
| 62 | 62 |
| 63 void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) { | 63 void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) { |
| 64 bool handled = true; | 64 bool handled = true; |
| 65 | 65 |
| 66 // When you add a new message handler, you should consider adding a similar | 66 // When you add a new message handler, you should consider adding a similar |
| 67 // handler in ServiceWorkerMessageFilter to release references passed from | 67 // handler in ServiceWorkerMessageFilter to release references passed from |
| 68 // the browser process in case we fail to post task to the thread. | 68 // the browser process in case we fail to post task to the thread. |
| 69 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg) | 69 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg) |
| 70 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_AssociateRegistration, | 70 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_AssociateRegistration, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 | 138 |
| 139 int request_id = pending_registration_callbacks_.Add(std::move(callbacks)); | 139 int request_id = pending_registration_callbacks_.Add(std::move(callbacks)); |
| 140 ServiceWorkerRegistrationOptions options(pattern); | 140 ServiceWorkerRegistrationOptions options(pattern); |
| 141 | 141 |
| 142 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker", | 142 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker", |
| 143 "ServiceWorkerDispatcher::RegisterServiceWorker", | 143 "ServiceWorkerDispatcher::RegisterServiceWorker", |
| 144 request_id, | 144 request_id, |
| 145 "Scope", pattern.spec(), | 145 "Scope", pattern.spec(), |
| 146 "Script URL", script_url.spec()); | 146 "Script URL", script_url.spec()); |
| 147 thread_safe_sender_->Send(new ServiceWorkerHostMsg_RegisterServiceWorker( | 147 thread_safe_sender_->Send(new ServiceWorkerHostMsg_RegisterServiceWorker( |
| 148 CurrentWorkerId(), request_id, provider_id, script_url, options)); | 148 ServiceWorkerCurrentWorkerId(), request_id, provider_id, script_url, optio
ns)); |
| 149 } | 149 } |
| 150 | 150 |
| 151 void ServiceWorkerDispatcher::UpdateServiceWorker( | 151 void ServiceWorkerDispatcher::UpdateServiceWorker( |
| 152 int provider_id, | 152 int provider_id, |
| 153 int64_t registration_id, | 153 int64_t registration_id, |
| 154 std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) { | 154 std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) { |
| 155 DCHECK(callbacks); | 155 DCHECK(callbacks); |
| 156 int request_id = pending_update_callbacks_.Add(std::move(callbacks)); | 156 int request_id = pending_update_callbacks_.Add(std::move(callbacks)); |
| 157 thread_safe_sender_->Send(new ServiceWorkerHostMsg_UpdateServiceWorker( | 157 thread_safe_sender_->Send(new ServiceWorkerHostMsg_UpdateServiceWorker( |
| 158 CurrentWorkerId(), request_id, provider_id, registration_id)); | 158 ServiceWorkerCurrentWorkerId(), request_id, provider_id, registration_id))
; |
| 159 } | 159 } |
| 160 | 160 |
| 161 void ServiceWorkerDispatcher::UnregisterServiceWorker( | 161 void ServiceWorkerDispatcher::UnregisterServiceWorker( |
| 162 int provider_id, | 162 int provider_id, |
| 163 int64_t registration_id, | 163 int64_t registration_id, |
| 164 std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks) { | 164 std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks) { |
| 165 DCHECK(callbacks); | 165 DCHECK(callbacks); |
| 166 int request_id = pending_unregistration_callbacks_.Add(std::move(callbacks)); | 166 int request_id = pending_unregistration_callbacks_.Add(std::move(callbacks)); |
| 167 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", | 167 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", |
| 168 "ServiceWorkerDispatcher::UnregisterServiceWorker", | 168 "ServiceWorkerDispatcher::UnregisterServiceWorker", |
| 169 request_id, "Registration ID", registration_id); | 169 request_id, "Registration ID", registration_id); |
| 170 thread_safe_sender_->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker( | 170 thread_safe_sender_->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker( |
| 171 CurrentWorkerId(), request_id, provider_id, registration_id)); | 171 ServiceWorkerCurrentWorkerId(), request_id, provider_id, registration_id))
; |
| 172 } | 172 } |
| 173 | 173 |
| 174 void ServiceWorkerDispatcher::GetRegistration( | 174 void ServiceWorkerDispatcher::GetRegistration( |
| 175 int provider_id, | 175 int provider_id, |
| 176 const GURL& document_url, | 176 const GURL& document_url, |
| 177 std::unique_ptr<WebServiceWorkerGetRegistrationCallbacks> callbacks) { | 177 std::unique_ptr<WebServiceWorkerGetRegistrationCallbacks> callbacks) { |
| 178 DCHECK(callbacks); | 178 DCHECK(callbacks); |
| 179 | 179 |
| 180 if (document_url.possibly_invalid_spec().size() > url::kMaxURLChars) { | 180 if (document_url.possibly_invalid_spec().size() > url::kMaxURLChars) { |
| 181 std::string error_message(kServiceWorkerGetRegistrationErrorPrefix); | 181 std::string error_message(kServiceWorkerGetRegistrationErrorPrefix); |
| 182 error_message += "The provided documentURL is too long."; | 182 error_message += "The provided documentURL is too long."; |
| 183 callbacks->OnError( | 183 callbacks->OnError( |
| 184 WebServiceWorkerError(WebServiceWorkerError::kErrorTypeSecurity, | 184 WebServiceWorkerError(WebServiceWorkerError::kErrorTypeSecurity, |
| 185 blink::WebString::FromASCII(error_message))); | 185 blink::WebString::FromASCII(error_message))); |
| 186 return; | 186 return; |
| 187 } | 187 } |
| 188 | 188 |
| 189 int request_id = | 189 int request_id = |
| 190 pending_get_registration_callbacks_.Add(std::move(callbacks)); | 190 pending_get_registration_callbacks_.Add(std::move(callbacks)); |
| 191 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", | 191 TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", |
| 192 "ServiceWorkerDispatcher::GetRegistration", | 192 "ServiceWorkerDispatcher::GetRegistration", |
| 193 request_id, | 193 request_id, |
| 194 "Document URL", document_url.spec()); | 194 "Document URL", document_url.spec()); |
| 195 thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetRegistration( | 195 thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetRegistration( |
| 196 CurrentWorkerId(), request_id, provider_id, document_url)); | 196 ServiceWorkerCurrentWorkerId(), request_id, provider_id, document_url)); |
| 197 } | 197 } |
| 198 | 198 |
| 199 void ServiceWorkerDispatcher::GetRegistrations( | 199 void ServiceWorkerDispatcher::GetRegistrations( |
| 200 int provider_id, | 200 int provider_id, |
| 201 std::unique_ptr<WebServiceWorkerGetRegistrationsCallbacks> callbacks) { | 201 std::unique_ptr<WebServiceWorkerGetRegistrationsCallbacks> callbacks) { |
| 202 DCHECK(callbacks); | 202 DCHECK(callbacks); |
| 203 | 203 |
| 204 int request_id = | 204 int request_id = |
| 205 pending_get_registrations_callbacks_.Add(std::move(callbacks)); | 205 pending_get_registrations_callbacks_.Add(std::move(callbacks)); |
| 206 | 206 |
| 207 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker", | 207 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker", |
| 208 "ServiceWorkerDispatcher::GetRegistrations", | 208 "ServiceWorkerDispatcher::GetRegistrations", |
| 209 request_id); | 209 request_id); |
| 210 thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetRegistrations( | 210 thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetRegistrations( |
| 211 CurrentWorkerId(), request_id, provider_id)); | 211 ServiceWorkerCurrentWorkerId(), request_id, provider_id)); |
| 212 } | 212 } |
| 213 | 213 |
| 214 void ServiceWorkerDispatcher::GetRegistrationForReady( | 214 void ServiceWorkerDispatcher::GetRegistrationForReady( |
| 215 int provider_id, | 215 int provider_id, |
| 216 std::unique_ptr<WebServiceWorkerGetRegistrationForReadyCallbacks> | 216 std::unique_ptr<WebServiceWorkerGetRegistrationForReadyCallbacks> |
| 217 callbacks) { | 217 callbacks) { |
| 218 int request_id = get_for_ready_callbacks_.Add(std::move(callbacks)); | 218 int request_id = get_for_ready_callbacks_.Add(std::move(callbacks)); |
| 219 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker", | 219 TRACE_EVENT_ASYNC_BEGIN0("ServiceWorker", |
| 220 "ServiceWorkerDispatcher::GetRegistrationForReady", | 220 "ServiceWorkerDispatcher::GetRegistrationForReady", |
| 221 request_id); | 221 request_id); |
| 222 thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetRegistrationForReady( | 222 thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetRegistrationForReady( |
| 223 CurrentWorkerId(), request_id, provider_id)); | 223 ServiceWorkerCurrentWorkerId(), request_id, provider_id)); |
| 224 } | 224 } |
| 225 | 225 |
| 226 void ServiceWorkerDispatcher::EnableNavigationPreload( | 226 void ServiceWorkerDispatcher::EnableNavigationPreload( |
| 227 int provider_id, | 227 int provider_id, |
| 228 int64_t registration_id, | 228 int64_t registration_id, |
| 229 bool enable, | 229 bool enable, |
| 230 std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks) { | 230 std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks) { |
| 231 DCHECK(callbacks); | 231 DCHECK(callbacks); |
| 232 int request_id = | 232 int request_id = |
| 233 enable_navigation_preload_callbacks_.Add(std::move(callbacks)); | 233 enable_navigation_preload_callbacks_.Add(std::move(callbacks)); |
| 234 thread_safe_sender_->Send(new ServiceWorkerHostMsg_EnableNavigationPreload( | 234 thread_safe_sender_->Send(new ServiceWorkerHostMsg_EnableNavigationPreload( |
| 235 CurrentWorkerId(), request_id, provider_id, registration_id, enable)); | 235 ServiceWorkerCurrentWorkerId(), request_id, provider_id, registration_id,
enable)); |
| 236 } | 236 } |
| 237 | 237 |
| 238 void ServiceWorkerDispatcher::GetNavigationPreloadState( | 238 void ServiceWorkerDispatcher::GetNavigationPreloadState( |
| 239 int provider_id, | 239 int provider_id, |
| 240 int64_t registration_id, | 240 int64_t registration_id, |
| 241 std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks) { | 241 std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks) { |
| 242 DCHECK(callbacks); | 242 DCHECK(callbacks); |
| 243 int request_id = | 243 int request_id = |
| 244 get_navigation_preload_state_callbacks_.Add(std::move(callbacks)); | 244 get_navigation_preload_state_callbacks_.Add(std::move(callbacks)); |
| 245 thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetNavigationPreloadState( | 245 thread_safe_sender_->Send(new ServiceWorkerHostMsg_GetNavigationPreloadState( |
| 246 CurrentWorkerId(), request_id, provider_id, registration_id)); | 246 ServiceWorkerCurrentWorkerId(), request_id, provider_id, registration_id))
; |
| 247 } | 247 } |
| 248 | 248 |
| 249 void ServiceWorkerDispatcher::SetNavigationPreloadHeader( | 249 void ServiceWorkerDispatcher::SetNavigationPreloadHeader( |
| 250 int provider_id, | 250 int provider_id, |
| 251 int64_t registration_id, | 251 int64_t registration_id, |
| 252 const std::string& value, | 252 const std::string& value, |
| 253 std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks) { | 253 std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks) { |
| 254 DCHECK(callbacks); | 254 DCHECK(callbacks); |
| 255 int request_id = | 255 int request_id = |
| 256 set_navigation_preload_header_callbacks_.Add(std::move(callbacks)); | 256 set_navigation_preload_header_callbacks_.Add(std::move(callbacks)); |
| 257 thread_safe_sender_->Send(new ServiceWorkerHostMsg_SetNavigationPreloadHeader( | 257 thread_safe_sender_->Send(new ServiceWorkerHostMsg_SetNavigationPreloadHeader( |
| 258 CurrentWorkerId(), request_id, provider_id, registration_id, value)); | 258 ServiceWorkerCurrentWorkerId(), request_id, provider_id, registration_id,
value)); |
| 259 } | 259 } |
| 260 | 260 |
| 261 void ServiceWorkerDispatcher::AddProviderContext( | 261 void ServiceWorkerDispatcher::AddProviderContext( |
| 262 ServiceWorkerProviderContext* provider_context) { | 262 ServiceWorkerProviderContext* provider_context) { |
| 263 DCHECK(provider_context); | 263 DCHECK(provider_context); |
| 264 int provider_id = provider_context->provider_id(); | 264 int provider_id = provider_context->provider_id(); |
| 265 DCHECK(!base::ContainsKey(provider_contexts_, provider_id)); | 265 DCHECK(!base::ContainsKey(provider_contexts_, provider_id)); |
| 266 provider_contexts_[provider_id] = provider_context; | 266 provider_contexts_[provider_id] = provider_context; |
| 267 } | 267 } |
| 268 | 268 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 285 void ServiceWorkerDispatcher::RemoveProviderClient(int provider_id) { | 285 void ServiceWorkerDispatcher::RemoveProviderClient(int provider_id) { |
| 286 // This could be possibly called multiple times to ensure termination. | 286 // This could be possibly called multiple times to ensure termination. |
| 287 if (base::ContainsKey(provider_clients_, provider_id)) | 287 if (base::ContainsKey(provider_clients_, provider_id)) |
| 288 provider_clients_.erase(provider_id); | 288 provider_clients_.erase(provider_id); |
| 289 } | 289 } |
| 290 | 290 |
| 291 ServiceWorkerDispatcher* | 291 ServiceWorkerDispatcher* |
| 292 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( | 292 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( |
| 293 ThreadSafeSender* thread_safe_sender, | 293 ThreadSafeSender* thread_safe_sender, |
| 294 base::SingleThreadTaskRunner* main_thread_task_runner) { | 294 base::SingleThreadTaskRunner* main_thread_task_runner) { |
| 295 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { | 295 if (g_dispatcher_tls.Pointer()->Get() == kSWDispatcherHasBeenDeleted) { |
| 296 NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher."; | 296 NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher."; |
| 297 g_dispatcher_tls.Pointer()->Set(NULL); | 297 g_dispatcher_tls.Pointer()->Set(NULL); |
| 298 } | 298 } |
| 299 if (g_dispatcher_tls.Pointer()->Get()) | 299 if (g_dispatcher_tls.Pointer()->Get()) |
| 300 return static_cast<ServiceWorkerDispatcher*>( | 300 return static_cast<ServiceWorkerDispatcher*>( |
| 301 g_dispatcher_tls.Pointer()->Get()); | 301 g_dispatcher_tls.Pointer()->Get()); |
| 302 | 302 |
| 303 ServiceWorkerDispatcher* dispatcher = | 303 ServiceWorkerDispatcher* dispatcher = |
| 304 new ServiceWorkerDispatcher(thread_safe_sender, main_thread_task_runner); | 304 new ServiceWorkerDispatcher(thread_safe_sender, main_thread_task_runner); |
| 305 if (WorkerThread::GetCurrentId()) | 305 if (WorkerThread::GetCurrentId()) |
| 306 WorkerThread::AddObserver(dispatcher); | 306 WorkerThread::AddObserver(dispatcher); |
| 307 return dispatcher; | 307 return dispatcher; |
| 308 } | 308 } |
| 309 | 309 |
| 310 ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() { | 310 ServiceWorkerDispatcher* ServiceWorkerDispatcher::GetThreadSpecificInstance() { |
| 311 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) | 311 if (g_dispatcher_tls.Pointer()->Get() == kSWDispatcherHasBeenDeleted) |
| 312 return NULL; | 312 return NULL; |
| 313 return static_cast<ServiceWorkerDispatcher*>( | 313 return static_cast<ServiceWorkerDispatcher*>( |
| 314 g_dispatcher_tls.Pointer()->Get()); | 314 g_dispatcher_tls.Pointer()->Get()); |
| 315 } | 315 } |
| 316 | 316 |
| 317 void ServiceWorkerDispatcher::WillStopCurrentWorkerThread() { | 317 void ServiceWorkerDispatcher::WillStopCurrentWorkerThread() { |
| 318 delete this; | 318 delete this; |
| 319 } | 319 } |
| 320 | 320 |
| 321 scoped_refptr<WebServiceWorkerImpl> | 321 scoped_refptr<WebServiceWorkerImpl> |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 return ServiceWorkerRegistrationHandleReference::Adopt( | 929 return ServiceWorkerRegistrationHandleReference::Adopt( |
| 930 info, thread_safe_sender_.get()); | 930 info, thread_safe_sender_.get()); |
| 931 } | 931 } |
| 932 | 932 |
| 933 std::unique_ptr<ServiceWorkerHandleReference> ServiceWorkerDispatcher::Adopt( | 933 std::unique_ptr<ServiceWorkerHandleReference> ServiceWorkerDispatcher::Adopt( |
| 934 const ServiceWorkerObjectInfo& info) { | 934 const ServiceWorkerObjectInfo& info) { |
| 935 return ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get()); | 935 return ServiceWorkerHandleReference::Adopt(info, thread_safe_sender_.get()); |
| 936 } | 936 } |
| 937 | 937 |
| 938 } // namespace content | 938 } // namespace content |
| OLD | NEW |