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 "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
8 #include "base/threading/thread_local.h" | 8 #include "base/threading/thread_local.h" |
9 #include "content/child/service_worker/web_service_worker_impl.h" | 9 #include "content/child/service_worker/web_service_worker_impl.h" |
10 #include "content/child/thread_safe_sender.h" | 10 #include "content/child/thread_safe_sender.h" |
11 #include "content/common/service_worker_messages.h" | 11 #include "content/common/service_worker_messages.h" |
12 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" | 12 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" |
13 | 13 |
14 using WebKit::WebServiceWorkerError; | |
14 using WebKit::WebServiceWorkerProvider; | 15 using WebKit::WebServiceWorkerProvider; |
15 using base::ThreadLocalPointer; | 16 using base::ThreadLocalPointer; |
16 using webkit_glue::WorkerTaskRunner; | 17 using webkit_glue::WorkerTaskRunner; |
17 | 18 |
18 namespace content { | 19 namespace content { |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 base::LazyInstance<ThreadLocalPointer<ServiceWorkerDispatcher> >::Leaky | 23 base::LazyInstance<ThreadLocalPointer<ServiceWorkerDispatcher> >::Leaky |
23 g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER; | 24 g_dispatcher_tls = LAZY_INSTANCE_INITIALIZER; |
(...skipping 13 matching lines...) Expand all Loading... | |
37 g_dispatcher_tls.Pointer()->Set(this); | 38 g_dispatcher_tls.Pointer()->Set(this); |
38 } | 39 } |
39 | 40 |
40 ServiceWorkerDispatcher::~ServiceWorkerDispatcher() { | 41 ServiceWorkerDispatcher::~ServiceWorkerDispatcher() { |
41 g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); | 42 g_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); |
42 } | 43 } |
43 | 44 |
44 void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) { | 45 void ServiceWorkerDispatcher::OnMessageReceived(const IPC::Message& msg) { |
45 bool handled = true; | 46 bool handled = true; |
46 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg) | 47 IPC_BEGIN_MESSAGE_MAP(ServiceWorkerDispatcher, msg) |
47 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered, | 48 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistered, OnRegistered) |
48 OnServiceWorkerRegistered) | |
49 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered, | 49 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerUnregistered, |
50 OnServiceWorkerUnregistered) | 50 OnUnregistered) |
51 IPC_MESSAGE_HANDLER(ServiceWorkerMsg_ServiceWorkerRegistrationError, | |
52 OnRegistrationError) | |
51 IPC_MESSAGE_UNHANDLED(handled = false) | 53 IPC_MESSAGE_UNHANDLED(handled = false) |
52 IPC_END_MESSAGE_MAP() | 54 IPC_END_MESSAGE_MAP() |
53 DCHECK(handled) << "Unhandled message:" << msg.type(); | 55 DCHECK(handled) << "Unhandled message:" << msg.type(); |
54 } | 56 } |
55 | 57 |
56 bool ServiceWorkerDispatcher::Send(IPC::Message* msg) { | 58 bool ServiceWorkerDispatcher::Send(IPC::Message* msg) { |
57 return thread_safe_sender_->Send(msg); | 59 return thread_safe_sender_->Send(msg); |
58 } | 60 } |
59 | 61 |
60 void ServiceWorkerDispatcher::RegisterServiceWorker( | 62 void ServiceWorkerDispatcher::RegisterServiceWorker( |
(...skipping 12 matching lines...) Expand all Loading... | |
73 DCHECK(callbacks); | 75 DCHECK(callbacks); |
74 int request_id = pending_callbacks_.Add(callbacks); | 76 int request_id = pending_callbacks_.Add(callbacks); |
75 thread_safe_sender_->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker( | 77 thread_safe_sender_->Send(new ServiceWorkerHostMsg_UnregisterServiceWorker( |
76 CurrentWorkerId(), request_id, pattern)); | 78 CurrentWorkerId(), request_id, pattern)); |
77 } | 79 } |
78 | 80 |
79 ServiceWorkerDispatcher* ServiceWorkerDispatcher::ThreadSpecificInstance( | 81 ServiceWorkerDispatcher* ServiceWorkerDispatcher::ThreadSpecificInstance( |
80 ThreadSafeSender* thread_safe_sender) { | 82 ThreadSafeSender* thread_safe_sender) { |
81 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { | 83 if (g_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { |
82 NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher."; | 84 NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher."; |
83 g_dispatcher_tls.Pointer()->Set(NULL); | 85 g_dispatcher_tls.Pointer()->Set(NULL); |
michaeln
2013/10/28 20:46:35
I think i see the potential reason for the !callba
| |
84 } | 86 } |
85 if (g_dispatcher_tls.Pointer()->Get()) | 87 if (g_dispatcher_tls.Pointer()->Get()) |
86 return g_dispatcher_tls.Pointer()->Get(); | 88 return g_dispatcher_tls.Pointer()->Get(); |
87 | 89 |
88 ServiceWorkerDispatcher* dispatcher = | 90 ServiceWorkerDispatcher* dispatcher = |
89 new ServiceWorkerDispatcher(thread_safe_sender); | 91 new ServiceWorkerDispatcher(thread_safe_sender); |
90 if (WorkerTaskRunner::Instance()->CurrentWorkerId()) | 92 if (WorkerTaskRunner::Instance()->CurrentWorkerId()) |
91 webkit_glue::WorkerTaskRunner::Instance()->AddStopObserver(dispatcher); | 93 webkit_glue::WorkerTaskRunner::Instance()->AddStopObserver(dispatcher); |
92 return dispatcher; | 94 return dispatcher; |
93 } | 95 } |
94 | 96 |
95 void ServiceWorkerDispatcher::OnServiceWorkerRegistered( | 97 void ServiceWorkerDispatcher::OnRegistered( |
96 int32 thread_id, | 98 int32 thread_id, |
97 int32 request_id, | 99 int32 request_id, |
98 int64 service_worker_id) { | 100 int64 service_worker_id) { |
99 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks = | 101 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks = |
100 pending_callbacks_.Lookup(request_id); | 102 pending_callbacks_.Lookup(request_id); |
101 DCHECK(callbacks); | 103 DCHECK(callbacks); |
102 if (!callbacks) | 104 if (!callbacks) |
103 return; | 105 return; |
104 | 106 |
105 // the browser has to generate the service_worker_id so the same | 107 // the browser has to generate the service_worker_id so the same |
106 // worker can be called from different renderer contexts. However, | 108 // worker can be called from different renderer contexts. However, |
107 // the impl object doesn't have to be the same instance across calls | 109 // the impl object doesn't have to be the same instance across calls |
108 // unless we require the DOM objects to be identical when there's a | 110 // unless we require the DOM objects to be identical when there's a |
109 // duplicate registration. So for now we mint a new object each | 111 // duplicate registration. So for now we mint a new object each |
110 // time. | 112 // time. |
111 scoped_ptr<WebServiceWorkerImpl> worker( | 113 scoped_ptr<WebServiceWorkerImpl> worker( |
112 new WebServiceWorkerImpl(service_worker_id)); | 114 new WebServiceWorkerImpl(service_worker_id)); |
113 callbacks->onSuccess(worker.release()); | 115 callbacks->onSuccess(worker.release()); |
114 pending_callbacks_.Remove(request_id); | 116 pending_callbacks_.Remove(request_id); |
115 } | 117 } |
116 | 118 |
117 void ServiceWorkerDispatcher::OnServiceWorkerUnregistered( | 119 void ServiceWorkerDispatcher::OnUnregistered( |
118 int32 thread_id, | 120 int32 thread_id, |
119 int32 request_id) { | 121 int32 request_id) { |
120 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks = | 122 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks = |
121 pending_callbacks_.Lookup(request_id); | 123 pending_callbacks_.Lookup(request_id); |
122 DCHECK(callbacks); | 124 DCHECK(callbacks); |
123 if (!callbacks) | 125 if (!callbacks) |
124 return; | 126 return; |
125 | 127 |
126 callbacks->onSuccess(NULL); | 128 callbacks->onSuccess(NULL); |
127 pending_callbacks_.Remove(request_id); | 129 pending_callbacks_.Remove(request_id); |
128 } | 130 } |
129 | 131 |
132 void ServiceWorkerDispatcher::OnRegistrationError( | |
133 int32 thread_id, | |
134 int32 request_id, | |
135 WebServiceWorkerError::ErrorType error_type, | |
136 string16 message) { | |
137 WebServiceWorkerProvider::WebServiceWorkerCallbacks* callbacks = | |
138 pending_callbacks_.Lookup(request_id); | |
139 DCHECK(callbacks); | |
140 if (!callbacks) | |
michaeln
2013/10/25 21:41:25
do we need the test for !callback?
alecflett
2013/10/25 23:41:56
We've needed to do this for security reasons in ID
michaeln
2013/10/26 00:41:01
that makes good sense to me in the browser process
alecflett
2013/10/28 17:03:14
Agreed that it's certainly much safer in the brows
| |
141 return; | |
142 | |
143 scoped_ptr<WebServiceWorkerError> error( | |
144 new WebServiceWorkerError(error_type, message)); | |
145 callbacks->onError(error.release()); | |
146 pending_callbacks_.Remove(request_id); | |
147 } | |
148 | |
130 void ServiceWorkerDispatcher::OnWorkerRunLoopStopped() { delete this; } | 149 void ServiceWorkerDispatcher::OnWorkerRunLoopStopped() { delete this; } |
131 | 150 |
132 } // namespace content | 151 } // namespace content |
OLD | NEW |