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