Home | History | Annotate | Download | only in service_worker
      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
      3 // found in the LICENSE file.
      4 
      5 #include "content/browser/service_worker/service_worker_context_wrapper.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "base/threading/sequenced_worker_pool.h"
      9 #include "content/browser/service_worker/service_worker_context_core.h"
     10 #include "content/browser/service_worker/service_worker_context_observer.h"
     11 #include "content/browser/service_worker/service_worker_process_manager.h"
     12 #include "content/public/browser/browser_thread.h"
     13 #include "webkit/browser/quota/quota_manager_proxy.h"
     14 
     15 namespace content {
     16 
     17 ServiceWorkerContextWrapper::ServiceWorkerContextWrapper(
     18     BrowserContext* browser_context)
     19     : observer_list_(
     20           new ObserverListThreadSafe<ServiceWorkerContextObserver>()),
     21       process_manager_(new ServiceWorkerProcessManager(browser_context)) {
     22 }
     23 
     24 ServiceWorkerContextWrapper::~ServiceWorkerContextWrapper() {
     25 }
     26 
     27 void ServiceWorkerContextWrapper::Init(
     28     const base::FilePath& user_data_directory,
     29     quota::QuotaManagerProxy* quota_manager_proxy) {
     30   scoped_refptr<base::SequencedTaskRunner> database_task_runner =
     31       BrowserThread::GetBlockingPool()->
     32           GetSequencedTaskRunnerWithShutdownBehavior(
     33               BrowserThread::GetBlockingPool()->GetSequenceToken(),
     34               base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
     35   scoped_refptr<base::MessageLoopProxy> disk_cache_thread =
     36       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE);
     37   InitInternal(user_data_directory, database_task_runner,
     38                disk_cache_thread, quota_manager_proxy);
     39 }
     40 
     41 void ServiceWorkerContextWrapper::Shutdown() {
     42   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     43   process_manager_->Shutdown();
     44   BrowserThread::PostTask(
     45       BrowserThread::IO,
     46       FROM_HERE,
     47       base::Bind(&ServiceWorkerContextWrapper::ShutdownOnIO, this));
     48 }
     49 
     50 ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() {
     51   DCHECK_CURRENTLY_ON(BrowserThread::IO);
     52   return context_core_.get();
     53 }
     54 
     55 static void FinishRegistrationOnIO(
     56     const ServiceWorkerContext::ResultCallback& continuation,
     57     ServiceWorkerStatusCode status,
     58     int64 registration_id,
     59     int64 version_id) {
     60   DCHECK_CURRENTLY_ON(BrowserThread::IO);
     61   BrowserThread::PostTask(
     62       BrowserThread::UI,
     63       FROM_HERE,
     64       base::Bind(continuation, status == SERVICE_WORKER_OK));
     65 }
     66 
     67 void ServiceWorkerContextWrapper::RegisterServiceWorker(
     68     const GURL& pattern,
     69     const GURL& script_url,
     70     const ResultCallback& continuation) {
     71   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
     72     BrowserThread::PostTask(
     73         BrowserThread::IO,
     74         FROM_HERE,
     75         base::Bind(&ServiceWorkerContextWrapper::RegisterServiceWorker,
     76                    this,
     77                    pattern,
     78                    script_url,
     79                    continuation));
     80     return;
     81   }
     82 
     83   context()->RegisterServiceWorker(
     84       pattern,
     85       script_url,
     86       -1,
     87       NULL /* provider_host */,
     88       base::Bind(&FinishRegistrationOnIO, continuation));
     89 }
     90 
     91 static void FinishUnregistrationOnIO(
     92     const ServiceWorkerContext::ResultCallback& continuation,
     93     ServiceWorkerStatusCode status) {
     94   DCHECK_CURRENTLY_ON(BrowserThread::IO);
     95   BrowserThread::PostTask(
     96       BrowserThread::UI,
     97       FROM_HERE,
     98       base::Bind(continuation, status == SERVICE_WORKER_OK));
     99 }
    100 
    101 void ServiceWorkerContextWrapper::UnregisterServiceWorker(
    102     const GURL& pattern,
    103     const ResultCallback& continuation) {
    104   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
    105     BrowserThread::PostTask(
    106         BrowserThread::IO,
    107         FROM_HERE,
    108         base::Bind(&ServiceWorkerContextWrapper::UnregisterServiceWorker,
    109                    this,
    110                    pattern,
    111                    continuation));
    112     return;
    113   }
    114 
    115   context()->UnregisterServiceWorker(
    116       pattern,
    117       base::Bind(&FinishUnregistrationOnIO, continuation));
    118 }
    119 
    120 void ServiceWorkerContextWrapper::Terminate() {
    121   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    122   process_manager_->Shutdown();
    123 }
    124 
    125 void ServiceWorkerContextWrapper::AddObserver(
    126     ServiceWorkerContextObserver* observer) {
    127   observer_list_->AddObserver(observer);
    128 }
    129 
    130 void ServiceWorkerContextWrapper::RemoveObserver(
    131     ServiceWorkerContextObserver* observer) {
    132   observer_list_->RemoveObserver(observer);
    133 }
    134 
    135 void ServiceWorkerContextWrapper::InitInternal(
    136     const base::FilePath& user_data_directory,
    137     base::SequencedTaskRunner* database_task_runner,
    138     base::MessageLoopProxy* disk_cache_thread,
    139     quota::QuotaManagerProxy* quota_manager_proxy) {
    140   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
    141     BrowserThread::PostTask(
    142         BrowserThread::IO,
    143         FROM_HERE,
    144         base::Bind(&ServiceWorkerContextWrapper::InitInternal,
    145                    this,
    146                    user_data_directory,
    147                    make_scoped_refptr(database_task_runner),
    148                    make_scoped_refptr(disk_cache_thread),
    149                    make_scoped_refptr(quota_manager_proxy)));
    150     return;
    151   }
    152   DCHECK(!context_core_);
    153   context_core_.reset(new ServiceWorkerContextCore(user_data_directory,
    154                                                    database_task_runner,
    155                                                    disk_cache_thread,
    156                                                    quota_manager_proxy,
    157                                                    observer_list_,
    158                                                    this));
    159 }
    160 
    161 void ServiceWorkerContextWrapper::ShutdownOnIO() {
    162   DCHECK_CURRENTLY_ON(BrowserThread::IO);
    163   context_core_.reset();
    164 }
    165 
    166 }  // namespace content
    167