| 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/browser/service_worker/service_worker_version.h" | 5 #include "content/browser/service_worker/service_worker_version.h" |
| 6 | 6 |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "content/browser/service_worker/embedded_worker_instance.h" | 8 #include "content/browser/service_worker/embedded_worker_instance.h" |
| 9 #include "content/browser/service_worker/embedded_worker_registry.h" | 9 #include "content/browser/service_worker/embedded_worker_registry.h" |
| 10 #include "content/browser/service_worker/service_worker_context_core.h" | 10 #include "content/browser/service_worker/service_worker_context_core.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 void RunTaskAfterStartWorker( | 34 void RunTaskAfterStartWorker( |
| 35 base::WeakPtr<ServiceWorkerVersion> version, | 35 base::WeakPtr<ServiceWorkerVersion> version, |
| 36 const StatusCallback& error_callback, | 36 const StatusCallback& error_callback, |
| 37 const base::Closure& task, | 37 const base::Closure& task, |
| 38 ServiceWorkerStatusCode status) { | 38 ServiceWorkerStatusCode status) { |
| 39 if (status != SERVICE_WORKER_OK) { | 39 if (status != SERVICE_WORKER_OK) { |
| 40 if (!error_callback.is_null()) | 40 if (!error_callback.is_null()) |
| 41 error_callback.Run(status); | 41 error_callback.Run(status); |
| 42 return; | 42 return; |
| 43 } | 43 } |
| 44 if (version->status() != ServiceWorkerVersion::RUNNING) { | 44 if (version->running_status() != ServiceWorkerVersion::RUNNING) { |
| 45 // We've tried to start the worker (and it has succeeded), but | 45 // We've tried to start the worker (and it has succeeded), but |
| 46 // it looks it's not running yet. | 46 // it looks it's not running yet. |
| 47 NOTREACHED() << "The worker's not running after successful StartWorker"; | 47 NOTREACHED() << "The worker's not running after successful StartWorker"; |
| 48 if (!error_callback.is_null()) | 48 if (!error_callback.is_null()) |
| 49 error_callback.Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED); | 49 error_callback.Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED); |
| 50 return; | 50 return; |
| 51 } | 51 } |
| 52 task.Run(); | 52 task.Run(); |
| 53 } | 53 } |
| 54 | 54 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 callback.Run(status, result, response); | 91 callback.Run(status, result, response); |
| 92 } | 92 } |
| 93 | 93 |
| 94 } // namespace | 94 } // namespace |
| 95 | 95 |
| 96 ServiceWorkerVersion::ServiceWorkerVersion( | 96 ServiceWorkerVersion::ServiceWorkerVersion( |
| 97 ServiceWorkerRegistration* registration, | 97 ServiceWorkerRegistration* registration, |
| 98 EmbeddedWorkerRegistry* worker_registry, | 98 EmbeddedWorkerRegistry* worker_registry, |
| 99 int64 version_id) | 99 int64 version_id) |
| 100 : version_id_(version_id), | 100 : version_id_(version_id), |
| 101 status_(NEW), |
| 101 is_shutdown_(false), | 102 is_shutdown_(false), |
| 102 registration_(registration), | 103 registration_(registration), |
| 103 weak_factory_(this) { | 104 weak_factory_(this) { |
| 104 if (worker_registry) { | 105 if (worker_registry) { |
| 105 embedded_worker_ = worker_registry->CreateWorker(); | 106 embedded_worker_ = worker_registry->CreateWorker(); |
| 106 embedded_worker_->AddObserver(this); | 107 embedded_worker_->AddObserver(this); |
| 107 } | 108 } |
| 108 } | 109 } |
| 109 | 110 |
| 110 ServiceWorkerVersion::~ServiceWorkerVersion() { DCHECK(is_shutdown_); } | 111 ServiceWorkerVersion::~ServiceWorkerVersion() { DCHECK(is_shutdown_); } |
| 111 | 112 |
| 112 void ServiceWorkerVersion::Shutdown() { | 113 void ServiceWorkerVersion::Shutdown() { |
| 113 is_shutdown_ = true; | 114 is_shutdown_ = true; |
| 114 registration_ = NULL; | 115 registration_ = NULL; |
| 115 if (embedded_worker_) { | 116 if (embedded_worker_) { |
| 116 embedded_worker_->RemoveObserver(this); | 117 embedded_worker_->RemoveObserver(this); |
| 117 embedded_worker_.reset(); | 118 embedded_worker_.reset(); |
| 118 } | 119 } |
| 119 } | 120 } |
| 120 | 121 |
| 121 void ServiceWorkerVersion::StartWorker(const StatusCallback& callback) { | 122 void ServiceWorkerVersion::StartWorker(const StatusCallback& callback) { |
| 122 DCHECK(!is_shutdown_); | 123 DCHECK(!is_shutdown_); |
| 123 DCHECK(embedded_worker_); | 124 DCHECK(embedded_worker_); |
| 124 DCHECK(registration_); | 125 DCHECK(registration_); |
| 125 if (status() == RUNNING) { | 126 if (running_status() == RUNNING) { |
| 126 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 127 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
| 127 return; | 128 return; |
| 128 } | 129 } |
| 129 if (status() == STOPPING) { | 130 if (running_status() == STOPPING) { |
| 130 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); | 131 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED)); |
| 131 return; | 132 return; |
| 132 } | 133 } |
| 133 if (start_callbacks_.empty()) { | 134 if (start_callbacks_.empty()) { |
| 134 ServiceWorkerStatusCode status = embedded_worker_->Start( | 135 ServiceWorkerStatusCode status = embedded_worker_->Start( |
| 135 version_id_, | 136 version_id_, |
| 136 registration_->script_url()); | 137 registration_->script_url()); |
| 137 if (status != SERVICE_WORKER_OK) { | 138 if (status != SERVICE_WORKER_OK) { |
| 138 RunSoon(base::Bind(callback, status)); | 139 RunSoon(base::Bind(callback, status)); |
| 139 return; | 140 return; |
| 140 } | 141 } |
| 141 } | 142 } |
| 142 start_callbacks_.push_back(callback); | 143 start_callbacks_.push_back(callback); |
| 143 } | 144 } |
| 144 | 145 |
| 145 void ServiceWorkerVersion::StopWorker(const StatusCallback& callback) { | 146 void ServiceWorkerVersion::StopWorker(const StatusCallback& callback) { |
| 146 DCHECK(!is_shutdown_); | 147 DCHECK(!is_shutdown_); |
| 147 DCHECK(embedded_worker_); | 148 DCHECK(embedded_worker_); |
| 148 if (status() == STOPPED) { | 149 if (running_status() == STOPPED) { |
| 149 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 150 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
| 150 return; | 151 return; |
| 151 } | 152 } |
| 152 if (stop_callbacks_.empty()) { | 153 if (stop_callbacks_.empty()) { |
| 153 ServiceWorkerStatusCode status = embedded_worker_->Stop(); | 154 ServiceWorkerStatusCode status = embedded_worker_->Stop(); |
| 154 if (status != SERVICE_WORKER_OK) { | 155 if (status != SERVICE_WORKER_OK) { |
| 155 RunSoon(base::Bind(callback, status)); | 156 RunSoon(base::Bind(callback, status)); |
| 156 return; | 157 return; |
| 157 } | 158 } |
| 158 } | 159 } |
| 159 stop_callbacks_.push_back(callback); | 160 stop_callbacks_.push_back(callback); |
| 160 } | 161 } |
| 161 | 162 |
| 162 void ServiceWorkerVersion::SendMessage( | 163 void ServiceWorkerVersion::SendMessage( |
| 163 const IPC::Message& message, const StatusCallback& callback) { | 164 const IPC::Message& message, const StatusCallback& callback) { |
| 164 DCHECK(!is_shutdown_); | 165 DCHECK(!is_shutdown_); |
| 165 DCHECK(embedded_worker_); | 166 DCHECK(embedded_worker_); |
| 166 if (status() != RUNNING) { | 167 if (running_status() != RUNNING) { |
| 167 // Schedule calling this method after starting the worker. | 168 // Schedule calling this method after starting the worker. |
| 168 StartWorker(base::Bind(&RunTaskAfterStartWorker, | 169 StartWorker(base::Bind(&RunTaskAfterStartWorker, |
| 169 weak_factory_.GetWeakPtr(), callback, | 170 weak_factory_.GetWeakPtr(), callback, |
| 170 base::Bind(&self::SendMessage, | 171 base::Bind(&self::SendMessage, |
| 171 weak_factory_.GetWeakPtr(), | 172 weak_factory_.GetWeakPtr(), |
| 172 message, callback))); | 173 message, callback))); |
| 173 return; | 174 return; |
| 174 } | 175 } |
| 175 | 176 |
| 176 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( | 177 ServiceWorkerStatusCode status = embedded_worker_->SendMessage( |
| 177 kInvalidRequestId, message); | 178 kInvalidRequestId, message); |
| 178 RunSoon(base::Bind(callback, status)); | 179 RunSoon(base::Bind(callback, status)); |
| 179 } | 180 } |
| 180 | 181 |
| 181 void ServiceWorkerVersion::SendMessageAndRegisterCallback( | 182 void ServiceWorkerVersion::SendMessageAndRegisterCallback( |
| 182 const IPC::Message& message, const MessageCallback& callback) { | 183 const IPC::Message& message, const MessageCallback& callback) { |
| 183 DCHECK(!is_shutdown_); | 184 DCHECK(!is_shutdown_); |
| 184 DCHECK(embedded_worker_); | 185 DCHECK(embedded_worker_); |
| 185 if (status() != RUNNING) { | 186 if (running_status() != RUNNING) { |
| 186 // Schedule calling this method after starting the worker. | 187 // Schedule calling this method after starting the worker. |
| 187 StartWorker(base::Bind(&RunTaskAfterStartWorker, | 188 StartWorker(base::Bind(&RunTaskAfterStartWorker, |
| 188 weak_factory_.GetWeakPtr(), | 189 weak_factory_.GetWeakPtr(), |
| 189 base::Bind(&RunEmptyMessageCallback, callback), | 190 base::Bind(&RunEmptyMessageCallback, callback), |
| 190 base::Bind(&self::SendMessageAndRegisterCallback, | 191 base::Bind(&self::SendMessageAndRegisterCallback, |
| 191 weak_factory_.GetWeakPtr(), | 192 weak_factory_.GetWeakPtr(), |
| 192 message, callback))); | 193 message, callback))); |
| 193 return; | 194 return; |
| 194 } | 195 } |
| 195 | 196 |
| 196 int request_id = message_callbacks_.Add(new MessageCallback(callback)); | 197 int request_id = message_callbacks_.Add(new MessageCallback(callback)); |
| 197 ServiceWorkerStatusCode status = | 198 ServiceWorkerStatusCode status = |
| 198 embedded_worker_->SendMessage(request_id, message); | 199 embedded_worker_->SendMessage(request_id, message); |
| 199 if (status != SERVICE_WORKER_OK) { | 200 if (status != SERVICE_WORKER_OK) { |
| 200 message_callbacks_.Remove(request_id); | 201 message_callbacks_.Remove(request_id); |
| 201 RunSoon(base::Bind(callback, status, IPC::Message())); | 202 RunSoon(base::Bind(callback, status, IPC::Message())); |
| 202 return; | 203 return; |
| 203 } | 204 } |
| 204 } | 205 } |
| 205 | 206 |
| 206 void ServiceWorkerVersion::DispatchInstallEvent( | 207 void ServiceWorkerVersion::DispatchInstallEvent( |
| 207 int active_version_embedded_worker_id, | 208 int active_version_embedded_worker_id, |
| 208 const StatusCallback& callback) { | 209 const StatusCallback& callback) { |
| 210 if (status() != NEW) { |
| 211 // Unexpected. |
| 212 NOTREACHED(); |
| 213 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); |
| 214 return; |
| 215 } |
| 209 SendMessageAndRegisterCallback( | 216 SendMessageAndRegisterCallback( |
| 210 ServiceWorkerMsg_InstallEvent(active_version_embedded_worker_id), | 217 ServiceWorkerMsg_InstallEvent(active_version_embedded_worker_id), |
| 211 base::Bind(&HandleInstallFinished, callback)); | 218 base::Bind(&HandleInstallFinished, callback)); |
| 212 } | 219 } |
| 213 | 220 |
| 214 void ServiceWorkerVersion::DispatchFetchEvent( | 221 void ServiceWorkerVersion::DispatchFetchEvent( |
| 215 const ServiceWorkerFetchRequest& request, | 222 const ServiceWorkerFetchRequest& request, |
| 216 const FetchCallback& callback) { | 223 const FetchCallback& callback) { |
| 224 if (status() != ACTIVE) { |
| 225 // Unexpected. |
| 226 NOTREACHED(); |
| 227 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED, |
| 228 SERVICE_WORKER_FETCH_EVENT_RESULT_FALLBACK, |
| 229 ServiceWorkerResponse())); |
| 230 return; |
| 231 } |
| 217 SendMessageAndRegisterCallback( | 232 SendMessageAndRegisterCallback( |
| 218 ServiceWorkerMsg_FetchEvent(request), | 233 ServiceWorkerMsg_FetchEvent(request), |
| 219 base::Bind(&HandleFetchResponse, callback)); | 234 base::Bind(&HandleFetchResponse, callback)); |
| 220 } | 235 } |
| 221 | 236 |
| 222 void ServiceWorkerVersion::AddProcessToWorker(int process_id) { | 237 void ServiceWorkerVersion::AddProcessToWorker(int process_id) { |
| 223 DCHECK(!is_shutdown_); | 238 DCHECK(!is_shutdown_); |
| 224 embedded_worker_->AddProcessReference(process_id); | 239 embedded_worker_->AddProcessReference(process_id); |
| 225 } | 240 } |
| 226 | 241 |
| 227 void ServiceWorkerVersion::RemoveProcessToWorker(int process_id) { | 242 void ServiceWorkerVersion::RemoveProcessToWorker(int process_id) { |
| 228 embedded_worker_->ReleaseProcessReference(process_id); | 243 embedded_worker_->ReleaseProcessReference(process_id); |
| 229 } | 244 } |
| 230 | 245 |
| 231 void ServiceWorkerVersion::OnStarted() { | 246 void ServiceWorkerVersion::OnStarted() { |
| 232 DCHECK_EQ(RUNNING, status()); | 247 DCHECK_EQ(RUNNING, running_status()); |
| 233 // Fire all start callbacks. | 248 // Fire all start callbacks. |
| 234 RunCallbacks(start_callbacks_, SERVICE_WORKER_OK); | 249 RunCallbacks(start_callbacks_, SERVICE_WORKER_OK); |
| 235 start_callbacks_.clear(); | 250 start_callbacks_.clear(); |
| 236 } | 251 } |
| 237 | 252 |
| 238 void ServiceWorkerVersion::OnStopped() { | 253 void ServiceWorkerVersion::OnStopped() { |
| 239 DCHECK_EQ(STOPPED, status()); | 254 DCHECK_EQ(STOPPED, running_status()); |
| 240 // Fire all stop callbacks. | 255 // Fire all stop callbacks. |
| 241 RunCallbacks(stop_callbacks_, SERVICE_WORKER_OK); | 256 RunCallbacks(stop_callbacks_, SERVICE_WORKER_OK); |
| 242 stop_callbacks_.clear(); | 257 stop_callbacks_.clear(); |
| 243 | 258 |
| 244 // Let all start callbacks fail. | 259 // Let all start callbacks fail. |
| 245 RunCallbacks(start_callbacks_, SERVICE_WORKER_ERROR_START_WORKER_FAILED); | 260 RunCallbacks(start_callbacks_, SERVICE_WORKER_ERROR_START_WORKER_FAILED); |
| 246 start_callbacks_.clear(); | 261 start_callbacks_.clear(); |
| 247 | 262 |
| 248 // Let all message callbacks fail. | 263 // Let all message callbacks fail. |
| 249 // TODO(kinuko): Consider if we want to add queue+resend mechanism here. | 264 // TODO(kinuko): Consider if we want to add queue+resend mechanism here. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 261 if (callback) { | 276 if (callback) { |
| 262 callback->Run(SERVICE_WORKER_OK, message); | 277 callback->Run(SERVICE_WORKER_OK, message); |
| 263 message_callbacks_.Remove(request_id); | 278 message_callbacks_.Remove(request_id); |
| 264 return; | 279 return; |
| 265 } | 280 } |
| 266 NOTREACHED() << "Got unexpected message: " << request_id | 281 NOTREACHED() << "Got unexpected message: " << request_id |
| 267 << " " << message.type(); | 282 << " " << message.type(); |
| 268 } | 283 } |
| 269 | 284 |
| 270 } // namespace content | 285 } // namespace content |
| OLD | NEW |