#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() {
+ServiceWorkerContextWrapper::ServiceWorkerContextWrapper(
+ BrowserContext* browser_context)
+ : observer_list_(
+ new ObserverListThreadSafe<ServiceWorkerContextObserver>()),
+ browser_context_(browser_context) {
}
ServiceWorkerContextWrapper::~ServiceWorkerContextWrapper() {
void ServiceWorkerContextWrapper::Init(
const base::FilePath& user_data_directory,
quota::QuotaManagerProxy* quota_manager_proxy) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&ServiceWorkerContextWrapper::Init, this,
- user_data_directory,
- make_scoped_refptr(quota_manager_proxy)));
- return;
- }
- DCHECK(!context_core_);
- context_core_.reset(
- new ServiceWorkerContextCore(
- user_data_directory, quota_manager_proxy));
+ scoped_refptr<base::SequencedTaskRunner> database_task_runner =
+ BrowserThread::GetBlockingPool()->
+ GetSequencedTaskRunnerWithShutdownBehavior(
+ BrowserThread::GetBlockingPool()->GetSequenceToken(),
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+ InitInternal(user_data_directory, database_task_runner, quota_manager_proxy);
}
void ServiceWorkerContextWrapper::Shutdown() {
if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ browser_context_ = NULL;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&ServiceWorkerContextWrapper::Shutdown, this));
return;
}
+ // Breaks the reference cycle through ServiceWorkerProcessManager.
context_core_.reset();
}
ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ 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::AddObserver(
+ ServiceWorkerContextObserver* observer) {
+ observer_list_->AddObserver(observer);
+}
+
+void ServiceWorkerContextWrapper::RemoveObserver(
+ ServiceWorkerContextObserver* observer) {
+ observer_list_->RemoveObserver(observer);
+}
+
+void ServiceWorkerContextWrapper::InitForTesting(
+ const base::FilePath& user_data_directory,
+ base::SequencedTaskRunner* database_task_runner,
+ quota::QuotaManagerProxy* quota_manager_proxy) {
+ InitInternal(user_data_directory, database_task_runner, quota_manager_proxy);
+}
+
+void ServiceWorkerContextWrapper::InitInternal(
+ const base::FilePath& user_data_directory,
+ base::SequencedTaskRunner* database_task_runner,
+ 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(quota_manager_proxy)));
+ return;
+ }
+ DCHECK(!context_core_);
+ context_core_.reset(new ServiceWorkerContextCore(
+ user_data_directory,
+ database_task_runner,
+ quota_manager_proxy,
+ observer_list_,
+ make_scoped_ptr(new ServiceWorkerProcessManager(this))));
+}
+
} // namespace content