Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/service_worker/service_worker_storage.h" | 5 #include "content/browser/service_worker/service_worker_storage.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/sequenced_task_runner.h" | 11 #include "base/sequenced_task_runner.h" |
| 12 #include "base/task_runner_util.h" | 12 #include "base/task_runner_util.h" |
| 13 #include "content/browser/service_worker/service_worker_context_core.h" | 13 #include "content/browser/service_worker/service_worker_context_core.h" |
| 14 #include "content/browser/service_worker/service_worker_disk_cache.h" | 14 #include "content/browser/service_worker/service_worker_disk_cache.h" |
| 15 #include "content/browser/service_worker/service_worker_info.h" | 15 #include "content/browser/service_worker/service_worker_info.h" |
| 16 #include "content/browser/service_worker/service_worker_registration.h" | 16 #include "content/browser/service_worker/service_worker_registration.h" |
| 17 #include "content/browser/service_worker/service_worker_utils.h" | 17 #include "content/browser/service_worker/service_worker_utils.h" |
| 18 #include "content/browser/service_worker/service_worker_version.h" | 18 #include "content/browser/service_worker/service_worker_version.h" |
| 19 #include "content/common/service_worker/service_worker_types.h" | 19 #include "content/common/service_worker/service_worker_types.h" |
| 20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 21 #include "net/base/net_errors.h" | 21 #include "net/base/net_errors.h" |
| 22 #include "webkit/browser/quota/quota_manager_proxy.h" | 22 #include "webkit/browser/quota/quota_manager_proxy.h" |
| 23 | 23 |
| 24 namespace content { | 24 namespace content { |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 typedef base::Callback<void( | |
| 29 ServiceWorkerStorage::InitialData* data, | |
| 30 ServiceWorkerDatabase::Status status)> InitializeCallback; | |
| 31 typedef base::Callback<void( | |
| 32 const ServiceWorkerDatabase::RegistrationData& data, | |
| 33 const std::vector<ServiceWorkerDatabase::ResourceRecord>& resources, | |
| 34 ServiceWorkerDatabase::Status status)> ReadRegistrationCallback; | |
| 35 typedef base::Callback<void( | |
| 36 bool origin_is_deletable, | |
| 37 ServiceWorkerDatabase::Status status)> DeleteRegistrationCallback; | |
| 38 | |
| 39 void RunSoon(const tracked_objects::Location& from_here, | 28 void RunSoon(const tracked_objects::Location& from_here, |
| 40 const base::Closure& closure) { | 29 const base::Closure& closure) { |
| 41 base::MessageLoop::current()->PostTask(from_here, closure); | 30 base::MessageLoop::current()->PostTask(from_here, closure); |
| 42 } | 31 } |
| 43 | 32 |
| 44 void CompleteFindNow( | 33 void CompleteFindNow( |
| 45 const scoped_refptr<ServiceWorkerRegistration>& registration, | 34 const scoped_refptr<ServiceWorkerRegistration>& registration, |
| 46 ServiceWorkerStatusCode status, | 35 ServiceWorkerStatusCode status, |
| 47 const ServiceWorkerStorage::FindRegistrationCallback& callback) { | 36 const ServiceWorkerStorage::FindRegistrationCallback& callback) { |
| 48 callback.Run(status, registration); | 37 callback.Run(status, registration); |
| 49 } | 38 } |
| 50 | 39 |
| 51 void CompleteFindSoon( | 40 void CompleteFindSoon( |
| 52 const tracked_objects::Location& from_here, | 41 const tracked_objects::Location& from_here, |
| 53 const scoped_refptr<ServiceWorkerRegistration>& registration, | 42 const scoped_refptr<ServiceWorkerRegistration>& registration, |
| 54 ServiceWorkerStatusCode status, | 43 ServiceWorkerStatusCode status, |
| 55 const ServiceWorkerStorage::FindRegistrationCallback& callback) { | 44 const ServiceWorkerStorage::FindRegistrationCallback& callback) { |
| 56 RunSoon(from_here, base::Bind(callback, status, registration)); | 45 RunSoon(from_here, base::Bind(callback, status, registration)); |
| 57 } | 46 } |
| 58 | 47 |
| 59 const base::FilePath::CharType kServiceWorkerDirectory[] = | 48 const base::FilePath::CharType kServiceWorkerDirectory[] = |
| 60 FILE_PATH_LITERAL("Service Worker"); | 49 FILE_PATH_LITERAL("Service Worker"); |
| 61 const base::FilePath::CharType kDatabaseName[] = | 50 const base::FilePath::CharType kDatabaseName[] = |
| 62 FILE_PATH_LITERAL("Database"); | 51 FILE_PATH_LITERAL("Database"); |
| 52 const base::FilePath::CharType kDiskCacheName[] = | |
| 53 FILE_PATH_LITERAL("Cache"); | |
| 63 | 54 |
| 64 const int kMaxMemDiskCacheSize = 10 * 1024 * 1024; | 55 const int kMaxMemDiskCacheSize = 10 * 1024 * 1024; |
| 56 const int kMaxDiskCacheSize = 250 * 1024 * 1024; | |
| 65 | 57 |
| 66 void EmptyCompletionCallback(int) {} | 58 void EmptyCompletionCallback(int) {} |
| 67 | 59 |
| 68 ServiceWorkerStatusCode DatabaseStatusToStatusCode( | 60 ServiceWorkerStatusCode DatabaseStatusToStatusCode( |
| 69 ServiceWorkerDatabase::Status status) { | 61 ServiceWorkerDatabase::Status status) { |
| 70 switch (status) { | 62 switch (status) { |
| 71 case ServiceWorkerDatabase::STATUS_OK: | 63 case ServiceWorkerDatabase::STATUS_OK: |
| 72 return SERVICE_WORKER_OK; | 64 return SERVICE_WORKER_OK; |
| 73 case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND: | 65 case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND: |
| 74 return SERVICE_WORKER_ERROR_NOT_FOUND; | 66 return SERVICE_WORKER_ERROR_NOT_FOUND; |
| 75 default: | 67 default: |
| 76 return SERVICE_WORKER_ERROR_FAILED; | 68 return SERVICE_WORKER_ERROR_FAILED; |
| 77 } | 69 } |
| 78 } | 70 } |
| 79 | 71 |
| 80 void ReadInitialDataFromDB( | |
| 81 ServiceWorkerDatabase* database, | |
| 82 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
| 83 const InitializeCallback& callback) { | |
| 84 DCHECK(database); | |
| 85 scoped_ptr<ServiceWorkerStorage::InitialData> data( | |
| 86 new ServiceWorkerStorage::InitialData()); | |
| 87 | |
| 88 ServiceWorkerDatabase::Status status = | |
| 89 database->GetNextAvailableIds(&data->next_registration_id, | |
| 90 &data->next_version_id, | |
| 91 &data->next_resource_id); | |
| 92 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 93 original_task_runner->PostTask( | |
| 94 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); | |
| 95 return; | |
| 96 } | |
| 97 | |
| 98 status = database->GetOriginsWithRegistrations(&data->origins); | |
| 99 original_task_runner->PostTask( | |
| 100 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); | |
| 101 } | |
| 102 | |
| 103 void DeleteRegistrationFromDB( | |
| 104 ServiceWorkerDatabase* database, | |
| 105 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
| 106 int64 registration_id, | |
| 107 const GURL& origin, | |
| 108 const DeleteRegistrationCallback& callback) { | |
| 109 DCHECK(database); | |
| 110 ServiceWorkerDatabase::Status status = | |
| 111 database->DeleteRegistration(registration_id, origin); | |
| 112 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 113 original_task_runner->PostTask( | |
| 114 FROM_HERE, base::Bind(callback, false, status)); | |
| 115 return; | |
| 116 } | |
| 117 | |
| 118 // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the | |
| 119 // unique origin list. | |
| 120 std::vector<ServiceWorkerDatabase::RegistrationData> registrations; | |
| 121 status = database->GetRegistrationsForOrigin(origin, ®istrations); | |
| 122 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 123 original_task_runner->PostTask( | |
| 124 FROM_HERE, base::Bind(callback, false, status)); | |
| 125 return; | |
| 126 } | |
| 127 | |
| 128 bool deletable = registrations.empty(); | |
| 129 original_task_runner->PostTask( | |
| 130 FROM_HERE, base::Bind(callback, deletable, status)); | |
| 131 } | |
| 132 | |
| 133 } // namespace | 72 } // namespace |
| 134 | 73 |
| 135 ServiceWorkerStorage::InitialData::InitialData() | 74 ServiceWorkerStorage::InitialData::InitialData() |
| 136 : next_registration_id(kInvalidServiceWorkerRegistrationId), | 75 : next_registration_id(kInvalidServiceWorkerRegistrationId), |
| 137 next_version_id(kInvalidServiceWorkerVersionId), | 76 next_version_id(kInvalidServiceWorkerVersionId), |
| 138 next_resource_id(kInvalidServiceWorkerResourceId) { | 77 next_resource_id(kInvalidServiceWorkerResourceId) { |
| 139 } | 78 } |
| 140 | 79 |
| 141 ServiceWorkerStorage::InitialData::~InitialData() { | 80 ServiceWorkerStorage::InitialData::~InitialData() { |
| 142 } | 81 } |
| 143 | 82 |
| 144 ServiceWorkerStorage::ServiceWorkerStorage( | 83 ServiceWorkerStorage::ServiceWorkerStorage( |
| 145 const base::FilePath& path, | 84 const base::FilePath& path, |
| 146 base::WeakPtr<ServiceWorkerContextCore> context, | 85 base::WeakPtr<ServiceWorkerContextCore> context, |
| 147 base::SequencedTaskRunner* database_task_runner, | 86 base::SequencedTaskRunner* database_task_runner, |
| 148 base::MessageLoopProxy* disk_cache_thread, | 87 base::MessageLoopProxy* disk_cache_thread, |
| 149 quota::QuotaManagerProxy* quota_manager_proxy) | 88 quota::QuotaManagerProxy* quota_manager_proxy) |
| 150 : next_registration_id_(kInvalidServiceWorkerRegistrationId), | 89 : next_registration_id_(kInvalidServiceWorkerRegistrationId), |
| 151 next_version_id_(kInvalidServiceWorkerVersionId), | 90 next_version_id_(kInvalidServiceWorkerVersionId), |
| 152 next_resource_id_(kInvalidServiceWorkerResourceId), | 91 next_resource_id_(kInvalidServiceWorkerResourceId), |
| 153 state_(UNINITIALIZED), | 92 state_(UNINITIALIZED), |
| 154 context_(context), | 93 context_(context), |
| 155 database_task_runner_(database_task_runner), | 94 database_task_runner_(database_task_runner), |
| 156 disk_cache_thread_(disk_cache_thread), | 95 disk_cache_thread_(disk_cache_thread), |
| 157 quota_manager_proxy_(quota_manager_proxy), | 96 quota_manager_proxy_(quota_manager_proxy), |
| 97 is_purge_pending_(false), | |
| 158 weak_factory_(this) { | 98 weak_factory_(this) { |
| 159 if (!path.empty()) { | 99 if (!path.empty()) |
| 160 path_ = path.Append(kServiceWorkerDirectory); | 100 path_ = path.Append(kServiceWorkerDirectory); |
| 161 database_.reset(new ServiceWorkerDatabase(path_.Append(kDatabaseName))); | 101 database_.reset(new ServiceWorkerDatabase(GetDatabasePath())); |
| 162 } else { | |
| 163 // Create an in-memory database. | |
| 164 database_.reset(new ServiceWorkerDatabase(base::FilePath())); | |
| 165 } | |
| 166 } | 102 } |
| 167 | 103 |
| 168 ServiceWorkerStorage::~ServiceWorkerStorage() { | 104 ServiceWorkerStorage::~ServiceWorkerStorage() { |
| 169 weak_factory_.InvalidateWeakPtrs(); | 105 weak_factory_.InvalidateWeakPtrs(); |
| 170 database_task_runner_->DeleteSoon(FROM_HERE, database_.release()); | 106 database_task_runner_->DeleteSoon(FROM_HERE, database_.release()); |
| 171 } | 107 } |
| 172 | 108 |
| 109 void ServiceWorkerStorage::FindRegistrationForDocument( | |
| 110 const GURL& document_url, | |
| 111 const FindRegistrationCallback& callback) { | |
| 112 if (!LazyInitialize(base::Bind( | |
| 113 &ServiceWorkerStorage::FindRegistrationForDocument, | |
| 114 weak_factory_.GetWeakPtr(), document_url, callback))) { | |
| 115 if (state_ != INITIALIZING || !context_) { | |
| 116 CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(), | |
| 117 SERVICE_WORKER_ERROR_FAILED, callback); | |
| 118 } | |
| 119 return; | |
| 120 } | |
| 121 DCHECK_EQ(INITIALIZED, state_); | |
| 122 | |
| 123 // See if there are any stored registrations for the origin. | |
| 124 if (!ContainsKey(registered_origins_, document_url.GetOrigin())) { | |
| 125 // Look for something currently being installed. | |
| 126 scoped_refptr<ServiceWorkerRegistration> installing_registration = | |
| 127 FindInstallingRegistrationForDocument(document_url); | |
| 128 CompleteFindNow( | |
| 129 installing_registration, | |
| 130 installing_registration ? | |
| 131 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, | |
| 132 callback); | |
| 133 return; | |
| 134 } | |
| 135 | |
| 136 database_task_runner_->PostTask( | |
| 137 FROM_HERE, | |
| 138 base::Bind( | |
| 139 &FindForDocumentInDB, | |
| 140 database_.get(), | |
| 141 base::MessageLoopProxy::current(), | |
| 142 document_url, | |
| 143 base::Bind(&ServiceWorkerStorage::DidFindRegistrationForDocument, | |
| 144 weak_factory_.GetWeakPtr(), document_url, callback))); | |
| 145 } | |
| 146 | |
| 173 void ServiceWorkerStorage::FindRegistrationForPattern( | 147 void ServiceWorkerStorage::FindRegistrationForPattern( |
| 174 const GURL& scope, | 148 const GURL& scope, |
| 175 const FindRegistrationCallback& callback) { | 149 const FindRegistrationCallback& callback) { |
| 176 scoped_refptr<ServiceWorkerRegistration> null_registration; | |
| 177 if (!LazyInitialize(base::Bind( | 150 if (!LazyInitialize(base::Bind( |
| 178 &ServiceWorkerStorage::FindRegistrationForPattern, | 151 &ServiceWorkerStorage::FindRegistrationForPattern, |
| 179 weak_factory_.GetWeakPtr(), scope, callback))) { | 152 weak_factory_.GetWeakPtr(), scope, callback))) { |
| 180 if (state_ != INITIALIZING || !context_) { | 153 if (state_ != INITIALIZING || !context_) { |
| 181 CompleteFindSoon(FROM_HERE, null_registration, | 154 CompleteFindSoon(FROM_HERE, scoped_refptr<ServiceWorkerRegistration>(), |
| 182 SERVICE_WORKER_ERROR_FAILED, callback); | 155 SERVICE_WORKER_ERROR_FAILED, callback); |
| 183 } | 156 } |
| 184 return; | 157 return; |
| 185 } | 158 } |
| 186 DCHECK_EQ(INITIALIZED, state_); | 159 DCHECK_EQ(INITIALIZED, state_); |
| 187 | 160 |
| 188 // See if there are any stored registrations for the origin. | 161 // See if there are any stored registrations for the origin. |
| 189 if (!ContainsKey(registered_origins_, scope.GetOrigin())) { | 162 if (!ContainsKey(registered_origins_, scope.GetOrigin())) { |
| 190 // Look for something currently being installed. | 163 // Look for something currently being installed. |
| 191 scoped_refptr<ServiceWorkerRegistration> installing_registration = | 164 scoped_refptr<ServiceWorkerRegistration> installing_registration = |
| 192 FindInstallingRegistrationForPattern(scope); | 165 FindInstallingRegistrationForPattern(scope); |
| 193 if (installing_registration) { | |
| 194 CompleteFindSoon( | |
| 195 FROM_HERE, installing_registration, SERVICE_WORKER_OK, callback); | |
| 196 return; | |
| 197 } | |
| 198 CompleteFindSoon( | 166 CompleteFindSoon( |
| 199 FROM_HERE, null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback); | 167 FROM_HERE, installing_registration, |
| 168 installing_registration ? | |
| 169 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, | |
| 170 callback); | |
| 200 return; | 171 return; |
| 201 } | 172 } |
| 202 | 173 |
| 203 RegistrationList* registrations = new RegistrationList(); | 174 database_task_runner_->PostTask( |
| 204 PostTaskAndReplyWithResult( | |
| 205 database_task_runner_, | |
| 206 FROM_HERE, | 175 FROM_HERE, |
| 207 base::Bind(&ServiceWorkerDatabase::GetRegistrationsForOrigin, | 176 base::Bind( |
| 208 base::Unretained(database_.get()), | 177 &FindForPatternInDB, |
| 209 scope.GetOrigin(), base::Unretained(registrations)), | 178 database_.get(), |
| 210 base::Bind(&ServiceWorkerStorage::DidGetRegistrationsForPattern, | 179 base::MessageLoopProxy::current(), |
| 211 weak_factory_.GetWeakPtr(), scope, callback, | 180 scope, |
| 212 base::Owned(registrations))); | 181 base::Bind(&ServiceWorkerStorage::DidFindRegistrationForPattern, |
| 213 } | 182 weak_factory_.GetWeakPtr(), scope, callback))); |
| 214 | |
| 215 void ServiceWorkerStorage::FindRegistrationForDocument( | |
| 216 const GURL& document_url, | |
| 217 const FindRegistrationCallback& callback) { | |
| 218 scoped_refptr<ServiceWorkerRegistration> null_registration; | |
| 219 if (!LazyInitialize(base::Bind( | |
| 220 &ServiceWorkerStorage::FindRegistrationForDocument, | |
| 221 weak_factory_.GetWeakPtr(), document_url, callback))) { | |
| 222 if (state_ != INITIALIZING || !context_) | |
| 223 CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback); | |
| 224 return; | |
| 225 } | |
| 226 DCHECK_EQ(INITIALIZED, state_); | |
| 227 | |
| 228 // See if there are any stored registrations for the origin. | |
| 229 if (!ContainsKey(registered_origins_, document_url.GetOrigin())) { | |
| 230 // Look for something currently being installed. | |
| 231 scoped_refptr<ServiceWorkerRegistration> installing_registration = | |
| 232 FindInstallingRegistrationForDocument(document_url); | |
| 233 if (installing_registration) { | |
| 234 CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback); | |
| 235 return; | |
| 236 } | |
| 237 CompleteFindNow( | |
| 238 null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback); | |
| 239 return; | |
| 240 } | |
| 241 | |
| 242 RegistrationList* registrations = new RegistrationList(); | |
| 243 PostTaskAndReplyWithResult( | |
| 244 database_task_runner_, | |
| 245 FROM_HERE, | |
| 246 base::Bind(&ServiceWorkerDatabase::GetRegistrationsForOrigin, | |
| 247 base::Unretained(database_.get()), | |
| 248 document_url.GetOrigin(), base::Unretained(registrations)), | |
| 249 base::Bind(&ServiceWorkerStorage::DidGetRegistrationsForDocument, | |
| 250 weak_factory_.GetWeakPtr(), document_url, callback, | |
| 251 base::Owned(registrations))); | |
| 252 } | 183 } |
| 253 | 184 |
| 254 void ServiceWorkerStorage::FindRegistrationForId( | 185 void ServiceWorkerStorage::FindRegistrationForId( |
| 255 int64 registration_id, | 186 int64 registration_id, |
| 256 const GURL& origin, | 187 const GURL& origin, |
| 257 const FindRegistrationCallback& callback) { | 188 const FindRegistrationCallback& callback) { |
| 258 scoped_refptr<ServiceWorkerRegistration> null_registration; | |
| 259 if (!LazyInitialize(base::Bind( | 189 if (!LazyInitialize(base::Bind( |
| 260 &ServiceWorkerStorage::FindRegistrationForId, | 190 &ServiceWorkerStorage::FindRegistrationForId, |
| 261 weak_factory_.GetWeakPtr(), registration_id, origin, callback))) { | 191 weak_factory_.GetWeakPtr(), registration_id, origin, callback))) { |
| 262 if (state_ != INITIALIZING || !context_) | 192 if (state_ != INITIALIZING || !context_) { |
| 263 CompleteFindNow(null_registration, SERVICE_WORKER_ERROR_FAILED, callback); | 193 CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(), |
| 194 SERVICE_WORKER_ERROR_FAILED, callback); | |
| 195 } | |
| 264 return; | 196 return; |
| 265 } | 197 } |
| 266 DCHECK_EQ(INITIALIZED, state_); | 198 DCHECK_EQ(INITIALIZED, state_); |
| 267 | 199 |
| 268 // See if there are any stored registrations for the origin. | 200 // See if there are any stored registrations for the origin. |
| 269 if (!ContainsKey(registered_origins_, origin)) { | 201 if (!ContainsKey(registered_origins_, origin)) { |
| 270 // Look for somthing currently being installed. | 202 // Look for something currently being installed. |
| 271 scoped_refptr<ServiceWorkerRegistration> installing_registration = | 203 scoped_refptr<ServiceWorkerRegistration> installing_registration = |
| 272 FindInstallingRegistrationForId(registration_id); | 204 FindInstallingRegistrationForId(registration_id); |
| 273 if (installing_registration) { | |
| 274 CompleteFindNow(installing_registration, SERVICE_WORKER_OK, callback); | |
| 275 return; | |
| 276 } | |
| 277 CompleteFindNow( | 205 CompleteFindNow( |
| 278 null_registration, SERVICE_WORKER_ERROR_NOT_FOUND, callback); | 206 installing_registration, |
| 207 installing_registration ? | |
| 208 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, | |
| 209 callback); | |
| 279 return; | 210 return; |
| 280 } | 211 } |
| 281 | 212 |
| 282 scoped_refptr<ServiceWorkerRegistration> registration = | 213 scoped_refptr<ServiceWorkerRegistration> registration = |
| 283 context_->GetLiveRegistration(registration_id); | 214 context_->GetLiveRegistration(registration_id); |
| 284 if (registration) { | 215 if (registration) { |
| 285 CompleteFindNow(registration, SERVICE_WORKER_OK, callback); | 216 CompleteFindNow(registration, SERVICE_WORKER_OK, callback); |
| 286 return; | 217 return; |
| 287 } | 218 } |
| 288 | 219 |
| 289 ServiceWorkerDatabase::RegistrationData* data = | 220 database_task_runner_->PostTask( |
| 290 new ServiceWorkerDatabase::RegistrationData; | |
| 291 ResourceList* resources = new ResourceList; | |
| 292 PostTaskAndReplyWithResult( | |
| 293 database_task_runner_, | |
| 294 FROM_HERE, | 221 FROM_HERE, |
| 295 base::Bind(&ServiceWorkerDatabase::ReadRegistration, | 222 base::Bind(&FindForIdInDB, |
| 296 base::Unretained(database_.get()), | 223 database_.get(), |
| 224 base::MessageLoopProxy::current(), | |
| 297 registration_id, origin, | 225 registration_id, origin, |
| 298 base::Unretained(data), | 226 base::Bind(&ServiceWorkerStorage::DidFindRegistrationForId, |
| 299 base::Unretained(resources)), | 227 weak_factory_.GetWeakPtr(), callback))); |
| 300 base::Bind(&ServiceWorkerStorage::DidReadRegistrationForId, | |
| 301 weak_factory_.GetWeakPtr(), | |
| 302 callback, base::Owned(data), base::Owned(resources))); | |
| 303 } | 228 } |
| 304 | 229 |
| 305 void ServiceWorkerStorage::GetAllRegistrations( | 230 void ServiceWorkerStorage::GetAllRegistrations( |
| 306 const GetAllRegistrationInfosCallback& callback) { | 231 const GetAllRegistrationInfosCallback& callback) { |
| 307 if (!LazyInitialize(base::Bind( | 232 if (!LazyInitialize(base::Bind( |
| 308 &ServiceWorkerStorage::GetAllRegistrations, | 233 &ServiceWorkerStorage::GetAllRegistrations, |
| 309 weak_factory_.GetWeakPtr(), callback))) { | 234 weak_factory_.GetWeakPtr(), callback))) { |
| 310 if (state_ != INITIALIZING || !context_) { | 235 if (state_ != INITIALIZING || !context_) { |
| 311 RunSoon(FROM_HERE, base::Bind( | 236 RunSoon(FROM_HERE, base::Bind( |
| 312 callback, std::vector<ServiceWorkerRegistrationInfo>())); | 237 callback, std::vector<ServiceWorkerRegistrationInfo>())); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 ServiceWorkerDatabase::RegistrationData data; | 269 ServiceWorkerDatabase::RegistrationData data; |
| 345 data.registration_id = registration->id(); | 270 data.registration_id = registration->id(); |
| 346 data.scope = registration->pattern(); | 271 data.scope = registration->pattern(); |
| 347 data.script = registration->script_url(); | 272 data.script = registration->script_url(); |
| 348 data.has_fetch_handler = true; | 273 data.has_fetch_handler = true; |
| 349 data.version_id = version->version_id(); | 274 data.version_id = version->version_id(); |
| 350 data.last_update_check = base::Time::Now(); | 275 data.last_update_check = base::Time::Now(); |
| 351 data.is_active = false; // initially stored in the waiting state | 276 data.is_active = false; // initially stored in the waiting state |
| 352 | 277 |
| 353 ResourceList resources; | 278 ResourceList resources; |
| 354 PostTaskAndReplyWithResult( | 279 version->script_cache_map()->GetResources(&resources); |
| 355 database_task_runner_, | 280 |
| 281 database_task_runner_->PostTask( | |
| 356 FROM_HERE, | 282 FROM_HERE, |
| 357 base::Bind(&ServiceWorkerDatabase::WriteRegistration, | 283 base::Bind(&WriteRegistrationInDB, |
| 358 base::Unretained(database_.get()), data, resources), | 284 database_.get(), |
| 359 base::Bind(&ServiceWorkerStorage::DidStoreRegistration, | 285 base::MessageLoopProxy::current(), |
| 360 weak_factory_.GetWeakPtr(), | 286 data, resources, |
| 361 registration->script_url().GetOrigin(), | 287 base::Bind(&ServiceWorkerStorage::DidStoreRegistration, |
| 362 callback)); | 288 weak_factory_.GetWeakPtr(), |
| 289 callback))); | |
| 363 } | 290 } |
| 364 | 291 |
| 365 void ServiceWorkerStorage::UpdateToActiveState( | 292 void ServiceWorkerStorage::UpdateToActiveState( |
| 366 ServiceWorkerRegistration* registration, | 293 ServiceWorkerRegistration* registration, |
| 367 const StatusCallback& callback) { | 294 const StatusCallback& callback) { |
| 368 DCHECK(registration); | 295 DCHECK(registration); |
| 369 | 296 |
| 370 DCHECK(state_ == INITIALIZED || state_ == DISABLED); | 297 DCHECK(state_ == INITIALIZED || state_ == DISABLED); |
| 371 if (state_ != INITIALIZED || !context_) { | 298 if (state_ != INITIALIZED || !context_) { |
| 372 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); | 299 RunSoon(FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 446 void ServiceWorkerStorage::NotifyInstallingRegistration( | 373 void ServiceWorkerStorage::NotifyInstallingRegistration( |
| 447 ServiceWorkerRegistration* registration) { | 374 ServiceWorkerRegistration* registration) { |
| 448 installing_registrations_[registration->id()] = registration; | 375 installing_registrations_[registration->id()] = registration; |
| 449 } | 376 } |
| 450 | 377 |
| 451 void ServiceWorkerStorage::NotifyDoneInstallingRegistration( | 378 void ServiceWorkerStorage::NotifyDoneInstallingRegistration( |
| 452 ServiceWorkerRegistration* registration) { | 379 ServiceWorkerRegistration* registration) { |
| 453 installing_registrations_.erase(registration->id()); | 380 installing_registrations_.erase(registration->id()); |
| 454 } | 381 } |
| 455 | 382 |
| 383 base::FilePath ServiceWorkerStorage::GetDatabasePath() { | |
| 384 if (path_.empty()) | |
| 385 return base::FilePath(); | |
| 386 return path_.Append(kDatabaseName); | |
| 387 } | |
| 388 | |
| 389 base::FilePath ServiceWorkerStorage::GetDiskCachePath() { | |
| 390 if (path_.empty()) | |
| 391 return base::FilePath(); | |
| 392 return path_.Append(kDiskCacheName); | |
| 393 } | |
| 394 | |
| 456 bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) { | 395 bool ServiceWorkerStorage::LazyInitialize(const base::Closure& callback) { |
| 457 if (!context_) | 396 if (!context_) |
| 458 return false; | 397 return false; |
| 459 | 398 |
| 460 switch (state_) { | 399 switch (state_) { |
| 461 case INITIALIZED: | 400 case INITIALIZED: |
| 462 return true; | 401 return true; |
| 463 case DISABLED: | 402 case DISABLED: |
| 464 return false; | 403 return false; |
| 465 case INITIALIZING: | 404 case INITIALIZING: |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 state_ = DISABLED; | 439 state_ = DISABLED; |
| 501 } | 440 } |
| 502 | 441 |
| 503 for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin(); | 442 for (std::vector<base::Closure>::const_iterator it = pending_tasks_.begin(); |
| 504 it != pending_tasks_.end(); ++it) { | 443 it != pending_tasks_.end(); ++it) { |
| 505 RunSoon(FROM_HERE, *it); | 444 RunSoon(FROM_HERE, *it); |
| 506 } | 445 } |
| 507 pending_tasks_.clear(); | 446 pending_tasks_.clear(); |
| 508 } | 447 } |
| 509 | 448 |
| 510 void ServiceWorkerStorage::DidGetRegistrationsForPattern( | 449 void ServiceWorkerStorage::DidFindRegistrationForDocument( |
| 511 const GURL& scope, | |
| 512 const FindRegistrationCallback& callback, | |
| 513 RegistrationList* registrations, | |
| 514 ServiceWorkerDatabase::Status status) { | |
| 515 DCHECK(registrations); | |
| 516 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 517 // TODO(nhiroki): Handle database error (http://crbug.com/371675). | |
| 518 callback.Run(SERVICE_WORKER_ERROR_FAILED, | |
| 519 scoped_refptr<ServiceWorkerRegistration>()); | |
| 520 return; | |
| 521 } | |
| 522 | |
| 523 // Find one with a matching scope. | |
| 524 for (RegistrationList::const_iterator it = registrations->begin(); | |
| 525 it != registrations->end(); ++it) { | |
| 526 if (scope == it->scope) { | |
| 527 scoped_refptr<ServiceWorkerRegistration> registration = | |
| 528 context_->GetLiveRegistration(it->registration_id); | |
| 529 if (!registration) | |
| 530 registration = CreateRegistration(*it); | |
| 531 callback.Run(SERVICE_WORKER_OK, registration); | |
| 532 return; | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 // Look for something currently being installed. | |
| 537 scoped_refptr<ServiceWorkerRegistration> installing_registration = | |
| 538 FindInstallingRegistrationForPattern(scope); | |
| 539 if (installing_registration) { | |
| 540 callback.Run(SERVICE_WORKER_OK, installing_registration); | |
| 541 return; | |
| 542 } | |
| 543 | |
| 544 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND, | |
| 545 scoped_refptr<ServiceWorkerRegistration>()); | |
| 546 } | |
| 547 | |
| 548 void ServiceWorkerStorage::DidGetRegistrationsForDocument( | |
| 549 const GURL& document_url, | 450 const GURL& document_url, |
| 550 const FindRegistrationCallback& callback, | 451 const FindRegistrationCallback& callback, |
| 551 RegistrationList* registrations, | 452 const ServiceWorkerDatabase::RegistrationData& data, |
| 453 const ResourceList& resources, | |
| 552 ServiceWorkerDatabase::Status status) { | 454 ServiceWorkerDatabase::Status status) { |
| 553 DCHECK(registrations); | |
| 554 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 555 // TODO(nhiroki): Handle database error (http://crbug.com/371675). | |
| 556 callback.Run(SERVICE_WORKER_ERROR_FAILED, | |
| 557 scoped_refptr<ServiceWorkerRegistration>()); | |
| 558 return; | |
| 559 } | |
| 560 | |
| 561 // Find one with a pattern match. | |
| 562 for (RegistrationList::const_iterator it = registrations->begin(); | |
| 563 it != registrations->end(); ++it) { | |
| 564 // TODO(michaeln): if there are multiple matches the one with | |
| 565 // the longest scope should win. | |
| 566 if (ServiceWorkerUtils::ScopeMatches(it->scope, document_url)) { | |
| 567 scoped_refptr<ServiceWorkerRegistration> registration = | |
| 568 context_->GetLiveRegistration(it->registration_id); | |
| 569 if (registration) { | |
| 570 callback.Run(SERVICE_WORKER_OK, registration); | |
| 571 return; | |
| 572 } | |
| 573 callback.Run(SERVICE_WORKER_OK, CreateRegistration(*it)); | |
| 574 return; | |
| 575 } | |
| 576 } | |
| 577 | |
| 578 // Look for something currently being installed. | |
| 579 // TODO(michaeln): Should be mixed in with the stored registrations | |
| 580 // for this test. | |
| 581 scoped_refptr<ServiceWorkerRegistration> installing_registration = | |
| 582 FindInstallingRegistrationForDocument(document_url); | |
| 583 if (installing_registration) { | |
| 584 callback.Run(SERVICE_WORKER_OK, installing_registration); | |
| 585 return; | |
| 586 } | |
| 587 | |
| 588 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND, | |
| 589 scoped_refptr<ServiceWorkerRegistration>()); | |
| 590 } | |
| 591 | |
| 592 void ServiceWorkerStorage::DidReadRegistrationForId( | |
| 593 const FindRegistrationCallback& callback, | |
| 594 ServiceWorkerDatabase::RegistrationData* registration, | |
| 595 ResourceList* resources, | |
| 596 ServiceWorkerDatabase::Status status) { | |
| 597 DCHECK(registration); | |
| 598 DCHECK(resources); | |
| 599 | |
| 600 if (status == ServiceWorkerDatabase::STATUS_OK) { | 455 if (status == ServiceWorkerDatabase::STATUS_OK) { |
| 601 callback.Run(SERVICE_WORKER_OK, CreateRegistration(*registration)); | 456 callback.Run(SERVICE_WORKER_OK, GetOrCreateRegistration(data, resources)); |
| 602 return; | 457 return; |
| 603 } | 458 } |
| 604 | 459 |
| 605 if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { | 460 if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { |
| 606 // Look for somthing currently being installed. | 461 // Look for something currently being installed. |
| 607 scoped_refptr<ServiceWorkerRegistration> installing_registration = | 462 scoped_refptr<ServiceWorkerRegistration> installing_registration = |
| 608 FindInstallingRegistrationForId(registration->registration_id); | 463 FindInstallingRegistrationForDocument(document_url); |
| 609 if (installing_registration) { | 464 callback.Run(installing_registration ? |
| 610 callback.Run(SERVICE_WORKER_OK, installing_registration); | 465 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, |
| 611 return; | 466 installing_registration); |
| 612 } | |
| 613 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND, | |
| 614 scoped_refptr<ServiceWorkerRegistration>()); | |
| 615 return; | 467 return; |
| 616 } | 468 } |
| 617 | 469 |
| 618 // TODO(nhiroki): Handle database error (http://crbug.com/371675). | 470 // TODO(nhiroki): Handle database error (http://crbug.com/371675). |
| 619 callback.Run(DatabaseStatusToStatusCode(status), | 471 callback.Run(DatabaseStatusToStatusCode(status), |
| 620 scoped_refptr<ServiceWorkerRegistration>()); | 472 scoped_refptr<ServiceWorkerRegistration>()); |
| 621 return; | 473 } |
| 474 | |
| 475 void ServiceWorkerStorage::DidFindRegistrationForPattern( | |
| 476 const GURL& scope, | |
| 477 const FindRegistrationCallback& callback, | |
| 478 const ServiceWorkerDatabase::RegistrationData& data, | |
| 479 const ResourceList& resources, | |
| 480 ServiceWorkerDatabase::Status status) { | |
| 481 if (status == ServiceWorkerDatabase::STATUS_OK) { | |
| 482 callback.Run(SERVICE_WORKER_OK, GetOrCreateRegistration(data, resources)); | |
| 483 return; | |
| 484 } | |
| 485 | |
| 486 if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) { | |
| 487 scoped_refptr<ServiceWorkerRegistration> installing_registration = | |
| 488 FindInstallingRegistrationForPattern(scope); | |
| 489 callback.Run(installing_registration ? | |
| 490 SERVICE_WORKER_OK : SERVICE_WORKER_ERROR_NOT_FOUND, | |
| 491 installing_registration); | |
| 492 return; | |
| 493 } | |
| 494 | |
| 495 // TODO(nhiroki): Handle database error (http://crbug.com/371675). | |
| 496 callback.Run(DatabaseStatusToStatusCode(status), | |
| 497 scoped_refptr<ServiceWorkerRegistration>()); | |
| 498 } | |
| 499 | |
| 500 void ServiceWorkerStorage::DidFindRegistrationForId( | |
| 501 const FindRegistrationCallback& callback, | |
| 502 const ServiceWorkerDatabase::RegistrationData& data, | |
| 503 const ResourceList& resources, | |
| 504 ServiceWorkerDatabase::Status status) { | |
| 505 if (status == ServiceWorkerDatabase::STATUS_OK) { | |
| 506 callback.Run(SERVICE_WORKER_OK, | |
| 507 GetOrCreateRegistration(data, resources)); | |
| 508 return; | |
| 509 } | |
| 510 // TODO(nhiroki): Handle database error (http://crbug.com/371675). | |
| 511 callback.Run(DatabaseStatusToStatusCode(status), | |
| 512 scoped_refptr<ServiceWorkerRegistration>()); | |
| 622 } | 513 } |
| 623 | 514 |
| 624 void ServiceWorkerStorage::DidGetAllRegistrations( | 515 void ServiceWorkerStorage::DidGetAllRegistrations( |
| 625 const GetAllRegistrationInfosCallback& callback, | 516 const GetAllRegistrationInfosCallback& callback, |
| 626 RegistrationList* registrations, | 517 RegistrationList* registrations, |
| 627 ServiceWorkerDatabase::Status status) { | 518 ServiceWorkerDatabase::Status status) { |
| 628 DCHECK(registrations); | 519 DCHECK(registrations); |
| 629 if (status != ServiceWorkerDatabase::STATUS_OK) { | 520 if (status != ServiceWorkerDatabase::STATUS_OK) { |
| 630 // TODO(nhiroki): Handle database error (http://crbug.com/371675). | 521 // TODO(nhiroki): Handle database error (http://crbug.com/371675). |
| 631 callback.Run(std::vector<ServiceWorkerRegistrationInfo>()); | 522 callback.Run(std::vector<ServiceWorkerRegistrationInfo>()); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 661 installing_registrations_.begin(); | 552 installing_registrations_.begin(); |
| 662 it != installing_registrations_.end(); ++it) { | 553 it != installing_registrations_.end(); ++it) { |
| 663 if (pushed_registrations.insert(it->first).second) | 554 if (pushed_registrations.insert(it->first).second) |
| 664 infos.push_back(it->second->GetInfo()); | 555 infos.push_back(it->second->GetInfo()); |
| 665 } | 556 } |
| 666 | 557 |
| 667 callback.Run(infos); | 558 callback.Run(infos); |
| 668 } | 559 } |
| 669 | 560 |
| 670 void ServiceWorkerStorage::DidStoreRegistration( | 561 void ServiceWorkerStorage::DidStoreRegistration( |
| 562 const StatusCallback& callback, | |
| 671 const GURL& origin, | 563 const GURL& origin, |
| 672 const StatusCallback& callback, | 564 const std::vector<int64>& newly_purgeable_resources, |
| 673 ServiceWorkerDatabase::Status status) { | 565 ServiceWorkerDatabase::Status status) { |
| 674 if (status != ServiceWorkerDatabase::STATUS_OK) { | 566 if (status != ServiceWorkerDatabase::STATUS_OK) { |
| 675 // TODO(nhiroki): Handle database error (http://crbug.com/371675). | 567 // TODO(nhiroki): Handle database error (http://crbug.com/371675). |
| 676 callback.Run(DatabaseStatusToStatusCode(status)); | 568 callback.Run(DatabaseStatusToStatusCode(status)); |
| 677 return; | 569 return; |
| 678 } | 570 } |
| 679 registered_origins_.insert(origin); | 571 registered_origins_.insert(origin); |
| 680 callback.Run(SERVICE_WORKER_OK); | 572 callback.Run(SERVICE_WORKER_OK); |
| 573 StartPurgingResources(newly_purgeable_resources); | |
| 681 } | 574 } |
| 682 | 575 |
| 683 void ServiceWorkerStorage::DidUpdateToActiveState( | 576 void ServiceWorkerStorage::DidUpdateToActiveState( |
| 684 const StatusCallback& callback, | 577 const StatusCallback& callback, |
| 685 ServiceWorkerDatabase::Status status) { | 578 ServiceWorkerDatabase::Status status) { |
| 686 // TODO(nhiroki): Handle database error (http://crbug.com/371675). | 579 // TODO(nhiroki): Handle database error (http://crbug.com/371675). |
| 687 callback.Run(DatabaseStatusToStatusCode(status)); | 580 callback.Run(DatabaseStatusToStatusCode(status)); |
| 688 } | 581 } |
| 689 | 582 |
| 690 void ServiceWorkerStorage::DidDeleteRegistration( | 583 void ServiceWorkerStorage::DidDeleteRegistration( |
| 691 const GURL& origin, | 584 const GURL& origin, |
| 692 const StatusCallback& callback, | 585 const StatusCallback& callback, |
| 693 bool origin_is_deletable, | 586 bool origin_is_deletable, |
| 587 const std::vector<int64>& newly_purgeable_resources, | |
| 694 ServiceWorkerDatabase::Status status) { | 588 ServiceWorkerDatabase::Status status) { |
| 695 if (status != ServiceWorkerDatabase::STATUS_OK) { | 589 if (status != ServiceWorkerDatabase::STATUS_OK) { |
| 696 // TODO(nhiroki): Handle database error (http://crbug.com/371675). | 590 // TODO(nhiroki): Handle database error (http://crbug.com/371675). |
| 697 callback.Run(DatabaseStatusToStatusCode(status)); | 591 callback.Run(DatabaseStatusToStatusCode(status)); |
| 698 return; | 592 return; |
| 699 } | 593 } |
| 700 if (origin_is_deletable) | 594 if (origin_is_deletable) |
| 701 registered_origins_.erase(origin); | 595 registered_origins_.erase(origin); |
| 702 callback.Run(SERVICE_WORKER_OK); | 596 callback.Run(SERVICE_WORKER_OK); |
| 597 StartPurgingResources(newly_purgeable_resources); | |
| 703 } | 598 } |
| 704 | 599 |
| 705 scoped_refptr<ServiceWorkerRegistration> | 600 scoped_refptr<ServiceWorkerRegistration> |
| 706 ServiceWorkerStorage::CreateRegistration( | 601 ServiceWorkerStorage::GetOrCreateRegistration( |
| 707 const ServiceWorkerDatabase::RegistrationData& data) { | 602 const ServiceWorkerDatabase::RegistrationData& data, |
| 708 scoped_refptr<ServiceWorkerRegistration> registration( | 603 const ResourceList& resources) { |
| 709 new ServiceWorkerRegistration( | 604 scoped_refptr<ServiceWorkerRegistration> registration = |
| 710 data.scope, data.script, data.registration_id, context_)); | 605 context_->GetLiveRegistration(data.registration_id); |
| 606 if (registration) | |
| 607 return registration; | |
| 711 | 608 |
| 609 registration = new ServiceWorkerRegistration( | |
| 610 data.scope, data.script, data.registration_id, context_); | |
| 712 scoped_refptr<ServiceWorkerVersion> version = | 611 scoped_refptr<ServiceWorkerVersion> version = |
| 713 context_->GetLiveVersion(data.version_id); | 612 context_->GetLiveVersion(data.version_id); |
| 714 if (!version) { | 613 if (!version) { |
| 715 version = new ServiceWorkerVersion(registration, data.version_id, context_); | 614 version = new ServiceWorkerVersion(registration, data.version_id, context_); |
| 716 version->SetStatus(data.is_active ? | 615 version->SetStatus(data.is_active ? |
| 717 ServiceWorkerVersion::ACTIVE : ServiceWorkerVersion::INSTALLED); | 616 ServiceWorkerVersion::ACTIVE : ServiceWorkerVersion::INSTALLED); |
| 617 version->script_cache_map()->SetResources(resources); | |
| 718 } | 618 } |
| 719 | 619 |
| 720 if (version->status() == ServiceWorkerVersion::ACTIVE) | 620 if (version->status() == ServiceWorkerVersion::ACTIVE) |
| 721 registration->set_active_version(version); | 621 registration->set_active_version(version); |
| 722 else if (version->status() == ServiceWorkerVersion::INSTALLED) | 622 else if (version->status() == ServiceWorkerVersion::INSTALLED) |
| 723 registration->set_pending_version(version); | 623 registration->set_pending_version(version); |
| 724 else | 624 else |
| 725 NOTREACHED(); | 625 NOTREACHED(); |
| 726 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after | 626 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after |
| 727 // the Find result we're returning here? NOTREACHED condition? | 627 // the Find result we're returning here? NOTREACHED condition? |
| 728 | |
| 729 return registration; | 628 return registration; |
| 730 } | 629 } |
| 731 | 630 |
| 732 ServiceWorkerRegistration* | 631 ServiceWorkerRegistration* |
| 733 ServiceWorkerStorage::FindInstallingRegistrationForDocument( | 632 ServiceWorkerStorage::FindInstallingRegistrationForDocument( |
| 734 const GURL& document_url) { | 633 const GURL& document_url) { |
| 735 // TODO(michaeln): if there are multiple matches the one with | 634 // TODO(michaeln): if there are multiple matches the one with |
| 736 // the longest scope should win, and these should on equal footing | 635 // the longest scope should win. |
| 737 // with the stored registrations in FindRegistrationForDocument(). | |
| 738 for (RegistrationRefsById::const_iterator it = | 636 for (RegistrationRefsById::const_iterator it = |
| 739 installing_registrations_.begin(); | 637 installing_registrations_.begin(); |
| 740 it != installing_registrations_.end(); ++it) { | 638 it != installing_registrations_.end(); ++it) { |
| 741 if (ServiceWorkerUtils::ScopeMatches( | 639 if (ServiceWorkerUtils::ScopeMatches( |
| 742 it->second->pattern(), document_url)) { | 640 it->second->pattern(), document_url)) { |
| 743 return it->second; | 641 return it->second; |
| 744 } | 642 } |
| 745 } | 643 } |
| 746 return NULL; | 644 return NULL; |
| 747 } | 645 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 765 installing_registrations_.find(registration_id); | 663 installing_registrations_.find(registration_id); |
| 766 if (found == installing_registrations_.end()) | 664 if (found == installing_registrations_.end()) |
| 767 return NULL; | 665 return NULL; |
| 768 return found->second; | 666 return found->second; |
| 769 } | 667 } |
| 770 | 668 |
| 771 ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() { | 669 ServiceWorkerDiskCache* ServiceWorkerStorage::disk_cache() { |
| 772 if (disk_cache_) | 670 if (disk_cache_) |
| 773 return disk_cache_.get(); | 671 return disk_cache_.get(); |
| 774 | 672 |
| 775 // TODO(michaeln): Store data on disk and do error checking. | |
| 776 disk_cache_.reset(new ServiceWorkerDiskCache); | 673 disk_cache_.reset(new ServiceWorkerDiskCache); |
| 777 int rv = disk_cache_->InitWithMemBackend( | 674 |
| 778 kMaxMemDiskCacheSize, | 675 base::FilePath path = GetDiskCachePath(); |
| 779 base::Bind(&EmptyCompletionCallback)); | 676 if (path.empty()) { |
| 780 DCHECK_EQ(net::OK, rv); | 677 int rv = disk_cache_->InitWithMemBackend( |
| 678 kMaxMemDiskCacheSize, | |
| 679 base::Bind(&EmptyCompletionCallback)); | |
| 680 DCHECK_EQ(net::OK, rv); | |
| 681 return disk_cache_.get(); | |
| 682 } | |
| 683 | |
| 684 int rv = disk_cache_->InitWithDiskBackend( | |
| 685 path, kMaxDiskCacheSize, false, | |
| 686 disk_cache_thread_.get(), | |
| 687 base::Bind(&ServiceWorkerStorage::OnDiskCacheInitialized, | |
| 688 weak_factory_.GetWeakPtr())); | |
| 689 if (rv != net::ERR_IO_PENDING) | |
| 690 OnDiskCacheInitialized(rv); | |
| 691 | |
| 781 return disk_cache_.get(); | 692 return disk_cache_.get(); |
| 782 } | 693 } |
| 783 | 694 |
| 695 void ServiceWorkerStorage::OnDiskCacheInitialized(int rv) { | |
| 696 if (rv != net::OK) { | |
| 697 LOG(ERROR) << "Failed to open the serviceworker diskcache."; | |
| 698 // TODO(michaeln): DeleteAndStartOver() | |
| 699 disk_cache_->Disable(); | |
| 700 state_ = DISABLED; | |
| 701 } | |
| 702 } | |
| 703 | |
| 704 void ServiceWorkerStorage::StartPurgingResources( | |
| 705 const std::vector<int64>& ids) { | |
| 706 for (size_t i = 0; i < ids.size(); ++i) | |
| 707 purgeable_reource_ids_.push_back(ids[i]); | |
| 708 | |
| 709 if (purgeable_reource_ids_.empty() || is_purge_pending_) | |
| 710 return; | |
| 711 | |
| 712 // Do one at a time until we're done, use RunSoon to avoid recursion when | |
| 713 // DoomEntry returns immediately. | |
| 714 is_purge_pending_ = true; | |
| 715 int64 id = purgeable_reource_ids_.front(); | |
| 716 purgeable_reource_ids_.pop_front(); | |
| 717 RunSoon(FROM_HERE, | |
| 718 base::Bind(&ServiceWorkerStorage::PurgeResource, | |
| 719 weak_factory_.GetWeakPtr(), id)); | |
| 720 } | |
| 721 | |
| 722 void ServiceWorkerStorage::PurgeResource(int64 id) { | |
| 723 DCHECK(is_purge_pending_); | |
| 724 int rv = disk_cache()->DoomEntry( | |
| 725 id, base::Bind(&ServiceWorkerStorage::OnResourcePurged, | |
| 726 weak_factory_.GetWeakPtr(), id)); | |
| 727 if (rv != net::ERR_IO_PENDING) | |
| 728 OnResourcePurged(id, rv); | |
|
nhiroki
2014/05/22 01:20:13
I see... DoomEntry() will run the callback only wh
michaeln
2014/05/22 02:02:37
yes, that flavor of async or not completion is com
| |
| 729 } | |
| 730 | |
| 731 void ServiceWorkerStorage::OnResourcePurged(int64 id, int rv) { | |
| 732 DCHECK(is_purge_pending_); | |
| 733 is_purge_pending_ = false; | |
| 734 | |
| 735 database_task_runner_->PostTask( | |
| 736 FROM_HERE, | |
| 737 base::Bind(base::IgnoreResult( | |
| 738 &ServiceWorkerDatabase::ClearPurgeableResourceIds), | |
| 739 base::Unretained(database_.get()), | |
| 740 std::set<int64>(&id, &id + 1))); | |
| 741 | |
| 742 // Continue purging the remaining resources. | |
| 743 StartPurgingResources(std::vector<int64>()); | |
| 744 } | |
| 745 | |
| 746 void ServiceWorkerStorage::ReadInitialDataFromDB( | |
| 747 ServiceWorkerDatabase* database, | |
| 748 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
| 749 const InitializeCallback& callback) { | |
| 750 DCHECK(database); | |
| 751 scoped_ptr<ServiceWorkerStorage::InitialData> data( | |
| 752 new ServiceWorkerStorage::InitialData()); | |
| 753 | |
| 754 ServiceWorkerDatabase::Status status = | |
| 755 database->GetNextAvailableIds(&data->next_registration_id, | |
| 756 &data->next_version_id, | |
| 757 &data->next_resource_id); | |
| 758 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 759 original_task_runner->PostTask( | |
| 760 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); | |
| 761 return; | |
| 762 } | |
| 763 | |
| 764 status = database->GetOriginsWithRegistrations(&data->origins); | |
| 765 original_task_runner->PostTask( | |
| 766 FROM_HERE, base::Bind(callback, base::Owned(data.release()), status)); | |
| 767 } | |
| 768 | |
| 769 void ServiceWorkerStorage::DeleteRegistrationFromDB( | |
| 770 ServiceWorkerDatabase* database, | |
| 771 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
| 772 int64 registration_id, | |
| 773 const GURL& origin, | |
| 774 const DeleteRegistrationCallback& callback) { | |
| 775 DCHECK(database); | |
| 776 | |
| 777 std::vector<int64> newly_purgeable_resources; | |
| 778 ServiceWorkerDatabase::Status status = | |
| 779 database->DeleteRegistration(registration_id, origin, | |
| 780 &newly_purgeable_resources); | |
| 781 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 782 original_task_runner->PostTask( | |
| 783 FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status)); | |
| 784 return; | |
| 785 } | |
| 786 | |
| 787 // TODO(nhiroki): Add convenient method to ServiceWorkerDatabase to check the | |
| 788 // unique origin list. | |
| 789 std::vector<ServiceWorkerDatabase::RegistrationData> registrations; | |
| 790 status = database->GetRegistrationsForOrigin(origin, ®istrations); | |
| 791 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 792 original_task_runner->PostTask( | |
| 793 FROM_HERE, base::Bind(callback, false, std::vector<int64>(), status)); | |
| 794 return; | |
| 795 } | |
| 796 | |
| 797 bool deletable = registrations.empty(); | |
| 798 original_task_runner->PostTask( | |
| 799 FROM_HERE, base::Bind(callback, deletable, | |
| 800 newly_purgeable_resources, status)); | |
| 801 } | |
| 802 | |
| 803 void ServiceWorkerStorage::WriteRegistrationInDB( | |
| 804 ServiceWorkerDatabase* database, | |
| 805 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
| 806 const ServiceWorkerDatabase::RegistrationData& data, | |
| 807 const ResourceList& resources, | |
| 808 const WriteRegistrationCallback& callback) { | |
| 809 DCHECK(database); | |
| 810 std::vector<int64> newly_purgeable_resources; | |
| 811 ServiceWorkerDatabase::Status status = | |
| 812 database->WriteRegistration(data, resources, &newly_purgeable_resources); | |
| 813 original_task_runner->PostTask( | |
| 814 FROM_HERE, | |
| 815 base::Bind(callback, data.script.GetOrigin(), | |
| 816 newly_purgeable_resources, status)); | |
| 817 } | |
| 818 | |
| 819 void ServiceWorkerStorage::FindForDocumentInDB( | |
| 820 ServiceWorkerDatabase* database, | |
| 821 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
| 822 const GURL& document_url, | |
| 823 const FindInDBCallback& callback) { | |
| 824 GURL origin = document_url.GetOrigin(); | |
| 825 RegistrationList registrations; | |
| 826 ServiceWorkerDatabase::Status status = | |
| 827 database->GetRegistrationsForOrigin(origin, ®istrations); | |
| 828 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 829 original_task_runner->PostTask( | |
| 830 FROM_HERE, | |
| 831 base::Bind(callback, | |
| 832 ServiceWorkerDatabase::RegistrationData(), | |
| 833 ResourceList(), | |
| 834 status)); | |
| 835 return; | |
| 836 } | |
| 837 | |
| 838 // Find one with a pattern match. | |
| 839 // TODO(michaeln): if there are multiple matches the one with | |
| 840 // the longest scope should win. | |
| 841 ServiceWorkerDatabase::RegistrationData data; | |
| 842 ResourceList resources; | |
| 843 status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND; | |
| 844 for (RegistrationList::const_iterator it = registrations.begin(); | |
| 845 it != registrations.end(); ++it) { | |
| 846 if (!ServiceWorkerUtils::ScopeMatches(it->scope, document_url)) | |
| 847 continue; | |
| 848 status = database->ReadRegistration(it->registration_id, origin, | |
| 849 &data, &resources); | |
| 850 break; // We're done looping. | |
| 851 } | |
| 852 | |
| 853 original_task_runner->PostTask( | |
| 854 FROM_HERE, | |
| 855 base::Bind(callback, data, resources, status)); | |
| 856 } | |
| 857 | |
| 858 void ServiceWorkerStorage::FindForPatternInDB( | |
| 859 ServiceWorkerDatabase* database, | |
| 860 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
| 861 const GURL& scope, | |
| 862 const FindInDBCallback& callback) { | |
| 863 GURL origin = scope.GetOrigin(); | |
| 864 std::vector<ServiceWorkerDatabase::RegistrationData> registrations; | |
| 865 ServiceWorkerDatabase::Status status = | |
| 866 database->GetRegistrationsForOrigin(origin, ®istrations); | |
| 867 if (status != ServiceWorkerDatabase::STATUS_OK) { | |
| 868 original_task_runner->PostTask( | |
| 869 FROM_HERE, | |
| 870 base::Bind(callback, | |
| 871 ServiceWorkerDatabase::RegistrationData(), | |
| 872 ResourceList(), | |
| 873 status)); | |
| 874 return; | |
| 875 } | |
| 876 | |
| 877 // Find one with an exact matching scope. | |
| 878 ServiceWorkerDatabase::RegistrationData data; | |
| 879 ResourceList resources; | |
| 880 status = ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND; | |
| 881 for (RegistrationList::const_iterator it = registrations.begin(); | |
| 882 it != registrations.end(); ++it) { | |
| 883 if (scope != it->scope) | |
| 884 continue; | |
| 885 status = database->ReadRegistration(it->registration_id, origin, | |
| 886 &data, &resources); | |
| 887 break; // We're done looping. | |
| 888 } | |
| 889 | |
| 890 original_task_runner->PostTask( | |
| 891 FROM_HERE, | |
| 892 base::Bind(callback, data, resources, status)); | |
| 893 } | |
| 894 | |
| 895 void ServiceWorkerStorage::FindForIdInDB( | |
| 896 ServiceWorkerDatabase* database, | |
| 897 scoped_refptr<base::SequencedTaskRunner> original_task_runner, | |
| 898 int64 registration_id, | |
| 899 const GURL& origin, | |
| 900 const FindInDBCallback& callback) { | |
| 901 ServiceWorkerDatabase::RegistrationData data; | |
| 902 ResourceList resources; | |
| 903 ServiceWorkerDatabase::Status status = | |
| 904 database->ReadRegistration(registration_id, origin, &data, &resources); | |
| 905 original_task_runner->PostTask( | |
| 906 FROM_HERE, base::Bind(callback, data, resources, status)); | |
| 907 } | |
| 908 | |
| 784 } // namespace content | 909 } // namespace content |
| OLD | NEW |