Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / service_worker_context_wrapper.cc
index e423d70..fd808be 100644 (file)
@@ -5,13 +5,20 @@
 #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() {
@@ -20,33 +27,136 @@ 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