Chromium Code Reviews| 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_registration.h" | 5 #include "content/browser/service_worker/service_worker_registration.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "content/browser/service_worker/service_worker_context_core.h" | 9 #include "content/browser/service_worker/service_worker_context_core.h" |
| 10 #include "content/browser/service_worker/service_worker_context_wrapper.h" | |
| 10 #include "content/browser/service_worker/service_worker_info.h" | 11 #include "content/browser/service_worker/service_worker_info.h" |
| 11 #include "content/browser/service_worker/service_worker_metrics.h" | 12 #include "content/browser/service_worker/service_worker_metrics.h" |
| 12 #include "content/browser/service_worker/service_worker_register_job.h" | 13 #include "content/browser/service_worker/service_worker_register_job.h" |
| 13 #include "content/common/service_worker/service_worker_messages.h" | 14 #include "content/common/service_worker/service_worker_messages.h" |
| 14 #include "content/common/service_worker/service_worker_utils.h" | 15 #include "content/common/service_worker/service_worker_utils.h" |
| 15 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
| 16 | 17 |
| 17 namespace content { | 18 namespace content { |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 ServiceWorkerVersionInfo GetVersionInfo(ServiceWorkerVersion* version) { | 22 ServiceWorkerVersionInfo GetVersionInfo(ServiceWorkerVersion* version) { |
| 22 if (!version) | 23 if (!version) |
| 23 return ServiceWorkerVersionInfo(); | 24 return ServiceWorkerVersionInfo(); |
| 24 return version->GetInfo(); | 25 return version->GetInfo(); |
| 25 } | 26 } |
| 26 | 27 |
| 28 bool GetShutdownStatusOnUIThread( | |
| 29 scoped_refptr<ServiceWorkerContextWrapper> wrapper, | |
| 30 ServiceWorkerStatusCode status) { | |
| 31 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 32 return wrapper->process_manager()->IsShutdown(); | |
| 33 } | |
| 34 | |
| 27 } // namespace | 35 } // namespace |
| 28 | 36 |
| 29 ServiceWorkerRegistration::ServiceWorkerRegistration( | 37 ServiceWorkerRegistration::ServiceWorkerRegistration( |
| 30 const GURL& pattern, | 38 const GURL& pattern, |
| 31 int64_t registration_id, | 39 int64_t registration_id, |
| 32 base::WeakPtr<ServiceWorkerContextCore> context) | 40 base::WeakPtr<ServiceWorkerContextCore> context) |
| 33 : pattern_(pattern), | 41 : pattern_(pattern), |
| 34 registration_id_(registration_id), | 42 registration_id_(registration_id), |
| 35 is_deleted_(false), | 43 is_deleted_(false), |
| 36 is_uninstalling_(false), | 44 is_uninstalling_(false), |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 active_version_ = NULL; | 177 active_version_ = NULL; |
| 170 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION); | 178 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION); |
| 171 } | 179 } |
| 172 } | 180 } |
| 173 | 181 |
| 174 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() { | 182 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() { |
| 175 DCHECK(waiting_version()); | 183 DCHECK(waiting_version()); |
| 176 should_activate_when_ready_ = true; | 184 should_activate_when_ready_ = true; |
| 177 | 185 |
| 178 if (!active_version() || !active_version()->HasControllee() || | 186 if (!active_version() || !active_version()->HasControllee() || |
| 179 waiting_version()->skip_waiting()) | 187 waiting_version()->skip_waiting()) { |
| 180 ActivateWaitingVersion(); | 188 ActivateWaitingVersion(false); |
| 189 } | |
| 181 } | 190 } |
| 182 | 191 |
| 183 void ServiceWorkerRegistration::ClaimClients() { | 192 void ServiceWorkerRegistration::ClaimClients() { |
| 184 DCHECK(context_); | 193 DCHECK(context_); |
| 185 DCHECK(active_version()); | 194 DCHECK(active_version()); |
| 186 | 195 |
| 187 for (std::unique_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 196 for (std::unique_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
| 188 context_->GetProviderHostIterator(); | 197 context_->GetProviderHostIterator(); |
| 189 !it->IsAtEnd(); it->Advance()) { | 198 !it->IsAtEnd(); it->Advance()) { |
| 190 ServiceWorkerProviderHost* host = it->GetProviderHost(); | 199 ServiceWorkerProviderHost* host = it->GetProviderHost(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 most_recent_version)); | 245 most_recent_version)); |
| 237 } | 246 } |
| 238 | 247 |
| 239 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) { | 248 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) { |
| 240 if (!context_) | 249 if (!context_) |
| 241 return; | 250 return; |
| 242 DCHECK_EQ(active_version(), version); | 251 DCHECK_EQ(active_version(), version); |
| 243 if (is_uninstalling_) | 252 if (is_uninstalling_) |
| 244 Clear(); | 253 Clear(); |
| 245 else if (should_activate_when_ready_) | 254 else if (should_activate_when_ready_) |
| 246 ActivateWaitingVersion(); | 255 ActivateWaitingVersion(true); |
| 247 is_uninstalling_ = false; | 256 is_uninstalling_ = false; |
| 248 should_activate_when_ready_ = false; | 257 should_activate_when_ready_ = false; |
| 249 } | 258 } |
| 250 | 259 |
| 251 void ServiceWorkerRegistration::ActivateWaitingVersion() { | 260 void ServiceWorkerRegistration::ActivateWaitingVersion(bool delay) { |
| 252 DCHECK(context_); | 261 DCHECK(context_); |
| 253 DCHECK(waiting_version()); | 262 DCHECK(waiting_version()); |
| 254 DCHECK(should_activate_when_ready_); | 263 DCHECK(should_activate_when_ready_); |
| 255 should_activate_when_ready_ = false; | 264 should_activate_when_ready_ = false; |
| 256 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version(); | 265 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version(); |
| 257 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version(); | 266 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version(); |
| 258 | 267 |
| 259 if (activating_version->is_redundant()) | 268 if (activating_version->is_redundant()) |
| 260 return; // Activation is no longer relevant. | 269 return; // Activation is no longer relevant. |
| 261 | 270 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 276 SetActiveVersion(activating_version); | 285 SetActiveVersion(activating_version); |
| 277 | 286 |
| 278 // "8. Run the [[UpdateState]] algorithm passing registration.activeWorker and | 287 // "8. Run the [[UpdateState]] algorithm passing registration.activeWorker and |
| 279 // "activating" as arguments." | 288 // "activating" as arguments." |
| 280 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING); | 289 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING); |
| 281 // "9. Fire a simple event named controllerchange..." | 290 // "9. Fire a simple event named controllerchange..." |
| 282 if (activating_version->skip_waiting()) | 291 if (activating_version->skip_waiting()) |
| 283 FOR_EACH_OBSERVER(Listener, listeners_, OnSkippedWaiting(this)); | 292 FOR_EACH_OBSERVER(Listener, listeners_, OnSkippedWaiting(this)); |
| 284 | 293 |
| 285 // "10. Queue a task to fire an event named activate..." | 294 // "10. Queue a task to fire an event named activate..." |
| 295 // The browser could be shutting down. To avoid spurious start worker | |
| 296 // failures, wait a bit before continuing. | |
|
nhiroki
2016/06/01 05:51:47
Let me add this comment just for future reference.
falken
2016/06/01 09:20:05
Acknowledged.
| |
| 297 if (delay) { | |
| 298 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), | |
| 299 base::Bind(&ServiceWorkerRegistration::ContinueActivation, | |
| 300 this, activating_version)); | |
| 301 } else { | |
| 302 ContinueActivation(activating_version); | |
| 303 } | |
| 304 } | |
| 305 | |
| 306 void ServiceWorkerRegistration::ContinueActivation( | |
| 307 const scoped_refptr<ServiceWorkerVersion>& activating_version) { | |
| 308 if (!context_) | |
| 309 return; | |
| 310 if (active_version() != activating_version.get()) | |
| 311 return; | |
| 312 DCHECK_EQ(ServiceWorkerVersion::ACTIVATING, activating_version->status()); | |
| 286 activating_version->RunAfterStartWorker( | 313 activating_version->RunAfterStartWorker( |
| 287 ServiceWorkerMetrics::EventType::ACTIVATE, | 314 ServiceWorkerMetrics::EventType::ACTIVATE, |
| 288 base::Bind(&ServiceWorkerRegistration::DispatchActivateEvent, this, | 315 base::Bind(&ServiceWorkerRegistration::DispatchActivateEvent, this, |
| 289 activating_version), | 316 activating_version), |
| 290 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, this, | 317 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, this, |
| 291 activating_version)); | 318 activating_version)); |
| 292 } | 319 } |
| 293 | 320 |
| 294 void ServiceWorkerRegistration::DeleteVersion( | 321 void ServiceWorkerRegistration::DeleteVersion( |
| 295 const scoped_refptr<ServiceWorkerVersion>& version) { | 322 const scoped_refptr<ServiceWorkerVersion>& version) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 324 } | 351 } |
| 325 } | 352 } |
| 326 | 353 |
| 327 void ServiceWorkerRegistration::NotifyRegistrationFinished() { | 354 void ServiceWorkerRegistration::NotifyRegistrationFinished() { |
| 328 std::vector<base::Closure> callbacks; | 355 std::vector<base::Closure> callbacks; |
| 329 callbacks.swap(registration_finished_callbacks_); | 356 callbacks.swap(registration_finished_callbacks_); |
| 330 for (const auto& callback : callbacks) | 357 for (const auto& callback : callbacks) |
| 331 callback.Run(); | 358 callback.Run(); |
| 332 } | 359 } |
| 333 | 360 |
| 361 void ServiceWorkerRegistration::SetTimerTaskRunnerForTest( | |
| 362 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | |
| 363 timer_.SetTaskRunner(task_runner); | |
|
nhiroki
2016/06/01 05:51:47
std::move(task_runner) ?
falken
2016/06/01 09:20:05
Done.
| |
| 364 } | |
| 365 | |
| 334 void ServiceWorkerRegistration::RegisterRegistrationFinishedCallback( | 366 void ServiceWorkerRegistration::RegisterRegistrationFinishedCallback( |
| 335 const base::Closure& callback) { | 367 const base::Closure& callback) { |
| 336 // This should only be called if the registration is in progress. | 368 // This should only be called if the registration is in progress. |
| 337 DCHECK(!active_version() && !waiting_version() && !is_uninstalled() && | 369 DCHECK(!active_version() && !waiting_version() && !is_uninstalled() && |
| 338 !is_uninstalling()); | 370 !is_uninstalling()); |
| 339 registration_finished_callbacks_.push_back(callback); | 371 registration_finished_callbacks_.push_back(callback); |
| 340 } | 372 } |
| 341 | 373 |
| 342 void ServiceWorkerRegistration::DispatchActivateEvent( | 374 void ServiceWorkerRegistration::DispatchActivateEvent( |
| 343 const scoped_refptr<ServiceWorkerVersion>& activating_version) { | 375 const scoped_refptr<ServiceWorkerVersion>& activating_version) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 354 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, this, | 386 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, this, |
| 355 activating_version)); | 387 activating_version)); |
| 356 activating_version | 388 activating_version |
| 357 ->DispatchSimpleEvent<ServiceWorkerHostMsg_ActivateEventFinished>( | 389 ->DispatchSimpleEvent<ServiceWorkerHostMsg_ActivateEventFinished>( |
| 358 request_id, ServiceWorkerMsg_ActivateEvent(request_id)); | 390 request_id, ServiceWorkerMsg_ActivateEvent(request_id)); |
| 359 } | 391 } |
| 360 | 392 |
| 361 void ServiceWorkerRegistration::OnActivateEventFinished( | 393 void ServiceWorkerRegistration::OnActivateEventFinished( |
| 362 const scoped_refptr<ServiceWorkerVersion>& activating_version, | 394 const scoped_refptr<ServiceWorkerVersion>& activating_version, |
| 363 ServiceWorkerStatusCode status) { | 395 ServiceWorkerStatusCode status) { |
| 364 if (!context_ || activating_version != active_version() || | 396 ServiceWorkerMetrics::RecordActivateEventStatus(status); |
| 365 activating_version->status() != ServiceWorkerVersion::ACTIVATING) | 397 |
| 398 if (!context_) | |
| 366 return; | 399 return; |
| 367 | 400 |
| 368 // |status| is just for UMA. Once we've attempted to dispatch the activate | 401 if (status == SERVICE_WORKER_OK) { |
| 369 // event to an installed worker, it's committed to becoming active. | 402 CompleteActivation(activating_version, status, false); |
|
nhiroki
2016/06/01 05:51:47
Always recording OK w/ |is_shutdown = false| would
falken
2016/06/01 09:20:05
OK I went with checking the state always. I had wa
| |
| 370 ServiceWorkerMetrics::RecordActivateEventStatus(status); | 403 return; |
| 404 } | |
| 405 | |
| 406 // Activate is prone to failing due to shutdown, because it's triggered when | |
| 407 // tabs close. Try to detect that case. | |
| 408 BrowserThread::PostTaskAndReplyWithResult( | |
| 409 BrowserThread::UI, FROM_HERE, | |
| 410 base::Bind(&GetShutdownStatusOnUIThread, | |
| 411 make_scoped_refptr(context_->wrapper()), status), | |
| 412 base::Bind(&ServiceWorkerRegistration::CompleteActivation, this, | |
| 413 activating_version, status)); | |
| 414 } | |
| 415 | |
| 416 void ServiceWorkerRegistration::CompleteActivation( | |
| 417 const scoped_refptr<ServiceWorkerVersion>& activating_version, | |
| 418 ServiceWorkerStatusCode status, | |
| 419 bool is_shutdown) { | |
| 420 ServiceWorkerMetrics::RecordActivateEventStatusWithShutdownStatus( | |
| 421 status, is_shutdown); | |
| 422 if (!context_ || activating_version != active_version() || | |
| 423 activating_version->status() != ServiceWorkerVersion::ACTIVATING) { | |
| 424 return; | |
| 425 } | |
| 426 | |
| 427 if (is_shutdown) { | |
| 428 DCHECK_NE(SERVICE_WORKER_OK, status); | |
| 429 return; | |
| 430 } | |
| 371 | 431 |
| 372 // "Run the Update State algorithm passing registration's active worker and | 432 // "Run the Update State algorithm passing registration's active worker and |
| 373 // 'activated' as the arguments." | 433 // 'activated' as the arguments." |
| 374 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED); | 434 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED); |
| 375 context_->storage()->UpdateToActiveState( | 435 context_->storage()->UpdateToActiveState( |
| 376 this, base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 436 this, base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
| 377 } | 437 } |
| 378 | 438 |
| 379 void ServiceWorkerRegistration::OnDeleteFinished( | 439 void ServiceWorkerRegistration::OnDeleteFinished( |
| 380 ServiceWorkerStatusCode status) { | 440 ServiceWorkerStatusCode status) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 428 if (!context_) { | 488 if (!context_) { |
| 429 callback.Run(SERVICE_WORKER_ERROR_ABORT); | 489 callback.Run(SERVICE_WORKER_ERROR_ABORT); |
| 430 return; | 490 return; |
| 431 } | 491 } |
| 432 context_->storage()->NotifyDoneInstallingRegistration( | 492 context_->storage()->NotifyDoneInstallingRegistration( |
| 433 this, version.get(), status); | 493 this, version.get(), status); |
| 434 callback.Run(status); | 494 callback.Run(status); |
| 435 } | 495 } |
| 436 | 496 |
| 437 } // namespace content | 497 } // namespace content |
| OLD | NEW |