| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/service_worker/service_worker_context_wrapper.h" |
| |
| #include "base/files/file_path.h" |
| #include "base/threading/sequenced_worker_pool.h" |
| #include "content/browser/service_worker/service_worker_context_core.h" |
| #include "content/browser/service_worker/service_worker_context_observer.h" |
| #include "content/browser/service_worker/service_worker_process_manager.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "webkit/browser/quota/quota_manager_proxy.h" |
| |
| namespace content { |
| |
| ServiceWorkerContextWrapper::ServiceWorkerContextWrapper( |
| BrowserContext* browser_context) |
| : observer_list_( |
| new ObserverListThreadSafe<ServiceWorkerContextObserver>()), |
| process_manager_(new ServiceWorkerProcessManager(browser_context)) { |
| } |
| |
| ServiceWorkerContextWrapper::~ServiceWorkerContextWrapper() { |
| } |
| |
| void ServiceWorkerContextWrapper::Init( |
| const base::FilePath& user_data_directory, |
| quota::QuotaManagerProxy* quota_manager_proxy) { |
| scoped_refptr<base::SequencedTaskRunner> database_task_runner = |
| BrowserThread::GetBlockingPool()-> |
| GetSequencedTaskRunnerWithShutdownBehavior( |
| BrowserThread::GetBlockingPool()->GetSequenceToken(), |
| base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
| scoped_refptr<base::MessageLoopProxy> disk_cache_thread = |
| BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE); |
| InitInternal(user_data_directory, database_task_runner, |
| disk_cache_thread, quota_manager_proxy); |
| } |
| |
| void ServiceWorkerContextWrapper::Shutdown() { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| process_manager_->Shutdown(); |
| BrowserThread::PostTask( |
| BrowserThread::IO, |
| FROM_HERE, |
| base::Bind(&ServiceWorkerContextWrapper::ShutdownOnIO, this)); |
| } |
| |
| ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| return context_core_.get(); |
| } |
| |
| static void FinishRegistrationOnIO( |
| const ServiceWorkerContext::ResultCallback& continuation, |
| ServiceWorkerStatusCode status, |
| int64 registration_id, |
| int64 version_id) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| BrowserThread::PostTask( |
| BrowserThread::UI, |
| FROM_HERE, |
| base::Bind(continuation, status == SERVICE_WORKER_OK)); |
| } |
| |
| void ServiceWorkerContextWrapper::RegisterServiceWorker( |
| const GURL& pattern, |
| const GURL& script_url, |
| const ResultCallback& continuation) { |
| if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| BrowserThread::PostTask( |
| BrowserThread::IO, |
| FROM_HERE, |
| base::Bind(&ServiceWorkerContextWrapper::RegisterServiceWorker, |
| this, |
| pattern, |
| script_url, |
| continuation)); |
| return; |
| } |
| |
| context()->RegisterServiceWorker( |
| pattern, |
| script_url, |
| -1, |
| NULL /* provider_host */, |
| base::Bind(&FinishRegistrationOnIO, continuation)); |
| } |
| |
| static void FinishUnregistrationOnIO( |
| const ServiceWorkerContext::ResultCallback& continuation, |
| ServiceWorkerStatusCode status) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| BrowserThread::PostTask( |
| BrowserThread::UI, |
| FROM_HERE, |
| base::Bind(continuation, status == SERVICE_WORKER_OK)); |
| } |
| |
| void ServiceWorkerContextWrapper::UnregisterServiceWorker( |
| const GURL& pattern, |
| const ResultCallback& continuation) { |
| if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| BrowserThread::PostTask( |
| BrowserThread::IO, |
| FROM_HERE, |
| base::Bind(&ServiceWorkerContextWrapper::UnregisterServiceWorker, |
| this, |
| pattern, |
| continuation)); |
| return; |
| } |
| |
| context()->UnregisterServiceWorker( |
| pattern, |
| base::Bind(&FinishUnregistrationOnIO, continuation)); |
| } |
| |
| void ServiceWorkerContextWrapper::Terminate() { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| process_manager_->Shutdown(); |
| } |
| |
| void ServiceWorkerContextWrapper::AddObserver( |
| ServiceWorkerContextObserver* observer) { |
| observer_list_->AddObserver(observer); |
| } |
| |
| void ServiceWorkerContextWrapper::RemoveObserver( |
| ServiceWorkerContextObserver* observer) { |
| observer_list_->RemoveObserver(observer); |
| } |
| |
| void ServiceWorkerContextWrapper::InitInternal( |
| const base::FilePath& user_data_directory, |
| base::SequencedTaskRunner* database_task_runner, |
| base::MessageLoopProxy* disk_cache_thread, |
| quota::QuotaManagerProxy* quota_manager_proxy) { |
| if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| BrowserThread::PostTask( |
| BrowserThread::IO, |
| FROM_HERE, |
| base::Bind(&ServiceWorkerContextWrapper::InitInternal, |
| this, |
| user_data_directory, |
| make_scoped_refptr(database_task_runner), |
| make_scoped_refptr(disk_cache_thread), |
| make_scoped_refptr(quota_manager_proxy))); |
| return; |
| } |
| DCHECK(!context_core_); |
| context_core_.reset(new ServiceWorkerContextCore(user_data_directory, |
| database_task_runner, |
| disk_cache_thread, |
| quota_manager_proxy, |
| observer_list_, |
| this)); |
| } |
| |
| void ServiceWorkerContextWrapper::ShutdownOnIO() { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| context_core_.reset(); |
| } |
| |
| } // namespace content |