diff options
4 files changed, 129 insertions, 31 deletions
diff --git a/content/browser/service_worker/service_worker_provider_host_unittest.cc b/content/browser/service_worker/service_worker_provider_host_unittest.cc index 388e741..b627dff 100644 --- a/content/browser/service_worker/service_worker_provider_host_unittest.cc +++ b/content/browser/service_worker/service_worker_provider_host_unittest.cc @@ -151,44 +151,107 @@ TEST_F(ServiceWorkerProviderHostTest, ASSERT_FALSE(version_->HasProcessToRun()); } -class ServiceWorkerRegisterJobAndProviderHostTest - : public ServiceWorkerProviderHostTest { +class ServiceWorkerProviderHostPendingVersionTest : public testing::Test { protected: - ServiceWorkerRegisterJobAndProviderHostTest() {} - virtual ~ServiceWorkerRegisterJobAndProviderHostTest() {} + ServiceWorkerProviderHostPendingVersionTest() + : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), + next_provider_id_(1L) {} + virtual ~ServiceWorkerProviderHostPendingVersionTest() {} virtual void SetUp() OVERRIDE { - ServiceWorkerProviderHostTest::SetUp(); - register_job_.reset(new ServiceWorkerRegisterJob( - context_->AsWeakPtr(), scope_, script_url_)); - provider_host1_->set_document_url(GURL("http://www.example.com/foo")); - provider_host2_->set_document_url(GURL("http://www.example.com/bar")); - provider_host3_->set_document_url(GURL("http://www.example.ca/foo")); + context_.reset( + new ServiceWorkerContextCore(base::FilePath(), + base::MessageLoopProxy::current(), + base::MessageLoopProxy::current(), + NULL, + NULL, + NULL)); + + // Prepare provider hosts (for the same process). + provider_host1_ = CreateProviderHost(GURL("http://www.example.com/foo")); + provider_host2_ = CreateProviderHost(GURL("http://www.example.com/bar")); + provider_host3_ = CreateProviderHost(GURL("http://www.example.ca/foo")); + } + + base::WeakPtr<ServiceWorkerProviderHost> CreateProviderHost( + const GURL& document_url) { + scoped_ptr<ServiceWorkerProviderHost> host(new ServiceWorkerProviderHost( + kRenderProcessId, next_provider_id_++, context_->AsWeakPtr(), NULL)); + host->set_document_url(document_url); + base::WeakPtr<ServiceWorkerProviderHost> provider_host = host->AsWeakPtr(); + context_->AddProviderHost(host.Pass()); + return provider_host; } virtual void TearDown() OVERRIDE { - ServiceWorkerProviderHostTest::TearDown(); - register_job_.reset(); + context_.reset(); } - scoped_ptr<ServiceWorkerRegisterJob> register_job_; + content::TestBrowserThreadBundle thread_bundle_; + scoped_ptr<ServiceWorkerContextCore> context_; + base::WeakPtr<ServiceWorkerProviderHost> provider_host1_; + base::WeakPtr<ServiceWorkerProviderHost> provider_host2_; + base::WeakPtr<ServiceWorkerProviderHost> provider_host3_; private: - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegisterJobAndProviderHostTest); + int64 next_provider_id_; + + DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderHostPendingVersionTest); }; -// Test for ServiceWorkerRegisterJob::AssociatePendingVersionToDocuments. -TEST_F(ServiceWorkerRegisterJobAndProviderHostTest, +TEST_F(ServiceWorkerProviderHostPendingVersionTest, AssociatePendingVersionToDocuments) { - register_job_->AssociatePendingVersionToDocuments(version_.get()); - EXPECT_EQ(version_.get(), provider_host1_->pending_version()); - EXPECT_EQ(version_.get(), provider_host2_->pending_version()); + const GURL scope("http://www.example.com/*"); + const GURL script_url("http://www.example.com/service_worker.js"); + + scoped_refptr<ServiceWorkerRegistration> registration( + new ServiceWorkerRegistration( + scope, script_url, 1L, context_->AsWeakPtr())); + scoped_refptr<ServiceWorkerVersion> version( + new ServiceWorkerVersion(registration, 1L, context_->AsWeakPtr())); + + ServiceWorkerRegisterJob::AssociatePendingVersionToDocuments( + context_->AsWeakPtr(), version.get()); + EXPECT_EQ(version.get(), provider_host1_->pending_version()); + EXPECT_EQ(version.get(), provider_host2_->pending_version()); EXPECT_EQ(NULL, provider_host3_->pending_version()); +} - register_job_->AssociatePendingVersionToDocuments(NULL); +TEST_F(ServiceWorkerProviderHostPendingVersionTest, + DisassociatePendingVersionFromDocuments) { + const GURL scope1("http://www.example.com/*"); + const GURL script_url1("http://www.example.com/service_worker.js"); + scoped_refptr<ServiceWorkerRegistration> registration1( + new ServiceWorkerRegistration( + scope1, script_url1, 1L, context_->AsWeakPtr())); + scoped_refptr<ServiceWorkerVersion> version1( + new ServiceWorkerVersion(registration1, 1L, context_->AsWeakPtr())); + + const GURL scope2("http://www.example.ca/*"); + const GURL script_url2("http://www.example.ca/service_worker.js"); + scoped_refptr<ServiceWorkerRegistration> registration2( + new ServiceWorkerRegistration( + scope2, script_url2, 2L, context_->AsWeakPtr())); + scoped_refptr<ServiceWorkerVersion> version2( + new ServiceWorkerVersion(registration2, 2L, context_->AsWeakPtr())); + + ServiceWorkerRegisterJob::AssociatePendingVersionToDocuments( + context_->AsWeakPtr(), version1.get()); + ServiceWorkerRegisterJob::AssociatePendingVersionToDocuments( + context_->AsWeakPtr(), version2.get()); + + // Host1 and host2 are associated with version1 as a pending version, whereas + // host3 is associated with version2. + EXPECT_EQ(version1.get(), provider_host1_->pending_version()); + EXPECT_EQ(version1.get(), provider_host2_->pending_version()); + EXPECT_EQ(version2.get(), provider_host3_->pending_version()); + + // Disassociate version1 from host1 and host2. + ServiceWorkerRegisterJob::DisassociatePendingVersionFromDocuments( + context_->AsWeakPtr(), version1->version_id()); EXPECT_EQ(NULL, provider_host1_->pending_version()); EXPECT_EQ(NULL, provider_host2_->pending_version()); - EXPECT_EQ(NULL, provider_host3_->pending_version()); + EXPECT_EQ(version2.get(), provider_host3_->pending_version()); } } // namespace content diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc index 135a114..5f763f4 100644 --- a/content/browser/service_worker/service_worker_register_job.cc +++ b/content/browser/service_worker/service_worker_register_job.cc @@ -256,7 +256,7 @@ void ServiceWorkerRegisterJob::OnStartWorkerFinished( registration()->set_pending_version(pending_version()); ResolvePromise(status, registration(), pending_version()); - AssociatePendingVersionToDocuments(pending_version()); + AssociatePendingVersionToDocuments(context_, pending_version()); InstallAndContinue(); } @@ -325,8 +325,9 @@ void ServiceWorkerRegisterJob::ActivateAndContinue() { // "Set serviceWorkerRegistration.pendingWorker to null." // "Set serviceWorkerRegistration.activeWorker to activatingWorker." + DisassociatePendingVersionFromDocuments( + context_, pending_version()->version_id()); registration()->set_pending_version(NULL); - AssociatePendingVersionToDocuments(NULL); DCHECK(!registration()->active_version()); registration()->set_active_version(pending_version()); @@ -359,7 +360,8 @@ void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { SetPhase(COMPLETE); if (status != SERVICE_WORKER_OK) { if (registration() && registration()->pending_version()) { - AssociatePendingVersionToDocuments(NULL); + DisassociatePendingVersionFromDocuments( + context_, registration()->pending_version()->version_id()); registration()->set_pending_version(NULL); } if (registration() && !registration()->active_version()) { @@ -396,19 +398,41 @@ void ServiceWorkerRegisterJob::ResolvePromise( callbacks_.clear(); } +// static void ServiceWorkerRegisterJob::AssociatePendingVersionToDocuments( + base::WeakPtr<ServiceWorkerContextCore> context, ServiceWorkerVersion* version) { + DCHECK(context); + DCHECK(version); + // TODO(michaeln): This needs to respect the longest prefix wins // when it comes to finding a registration for a document url. // This should utilize storage->FindRegistrationForDocument(). for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = - context_->GetProviderHostIterator(); + context->GetProviderHostIterator(); + !it->IsAtEnd(); + it->Advance()) { + ServiceWorkerProviderHost* host = it->GetProviderHost(); + if (ServiceWorkerUtils::ScopeMatches(version->scope(), + host->document_url())) + host->SetPendingVersion(version); + } +} + +// static +void ServiceWorkerRegisterJob::DisassociatePendingVersionFromDocuments( + base::WeakPtr<ServiceWorkerContextCore> context, + int64 version_id) { + DCHECK(context); + for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = + context->GetProviderHostIterator(); !it->IsAtEnd(); it->Advance()) { - ServiceWorkerProviderHost* provider_host = it->GetProviderHost(); - if (ServiceWorkerUtils::ScopeMatches(pattern_, - provider_host->document_url())) - provider_host->SetPendingVersion(version); + ServiceWorkerProviderHost* host = it->GetProviderHost(); + if (host->pending_version() && + host->pending_version()->version_id() == version_id) { + host->SetPendingVersion(NULL); + } } } diff --git a/content/browser/service_worker/service_worker_register_job.h b/content/browser/service_worker/service_worker_register_job.h index 0a0c198..6a42b85 100644 --- a/content/browser/service_worker/service_worker_register_job.h +++ b/content/browser/service_worker/service_worker_register_job.h @@ -57,8 +57,10 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase { virtual RegistrationJobType GetType() OVERRIDE; private: - FRIEND_TEST_ALL_PREFIXES(ServiceWorkerRegisterJobAndProviderHostTest, + FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostPendingVersionTest, AssociatePendingVersionToDocuments); + FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostPendingVersionTest, + DisassociatePendingVersionFromDocuments); enum Phase { INITIAL, @@ -104,9 +106,17 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase { ServiceWorkerRegistration* registration, ServiceWorkerVersion* version); - CONTENT_EXPORT void AssociatePendingVersionToDocuments( + // Associates a pending version to documents matched with a scope of the + // version. + CONTENT_EXPORT static void AssociatePendingVersionToDocuments( + base::WeakPtr<ServiceWorkerContextCore> context, ServiceWorkerVersion* version); + // Disassociates a pending version specified by |version_id| from documents. + CONTENT_EXPORT static void DisassociatePendingVersionFromDocuments( + base::WeakPtr<ServiceWorkerContextCore> context, + int64 version_id); + // The ServiceWorkerContextCore object should always outlive this. base::WeakPtr<ServiceWorkerContextCore> context_; diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index e0dde76..4216454 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h @@ -98,6 +98,7 @@ class CONTENT_EXPORT ServiceWorkerVersion int64 version_id() const { return version_id_; } int64 registration_id() const { return registration_id_; } const GURL& script_url() const { return script_url_; } + const GURL& scope() const { return scope_; } RunningStatus running_status() const { return static_cast<RunningStatus>(embedded_worker_->status()); } |