| 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 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 9 #include "content/browser/service_worker/service_worker_context_core.h" | 10 #include "content/browser/service_worker/service_worker_context_core.h" |
| 11 #include "content/browser/service_worker/service_worker_database.pb.h" |
| 10 #include "content/browser/service_worker/service_worker_info.h" | 12 #include "content/browser/service_worker/service_worker_info.h" |
| 11 #include "content/browser/service_worker/service_worker_registration.h" | 13 #include "content/browser/service_worker/service_worker_registration.h" |
| 12 #include "content/browser/service_worker/service_worker_utils.h" | 14 #include "content/browser/service_worker/service_worker_utils.h" |
| 13 #include "content/browser/service_worker/service_worker_version.h" | 15 #include "content/browser/service_worker/service_worker_version.h" |
| 14 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
| 15 #include "webkit/browser/quota/quota_manager_proxy.h" | 17 #include "webkit/browser/quota/quota_manager_proxy.h" |
| 16 | 18 |
| 17 namespace content { | 19 namespace content { |
| 18 | 20 |
| 19 namespace { | 21 namespace { |
| 20 | 22 |
| 21 void RunSoon(const base::Closure& closure) { | 23 void RunSoon(const base::Closure& closure) { |
| 22 base::MessageLoop::current()->PostTask(FROM_HERE, closure); | 24 base::MessageLoop::current()->PostTask(FROM_HERE, closure); |
| 23 } | 25 } |
| 24 | 26 |
| 25 const base::FilePath::CharType kServiceWorkerDirectory[] = | 27 const base::FilePath::CharType kServiceWorkerDirectory[] = |
| 26 FILE_PATH_LITERAL("ServiceWorker"); | 28 FILE_PATH_LITERAL("ServiceWorker"); |
| 27 | 29 |
| 30 ServiceWorkerVersion::Status GetVersionStatus(bool is_active) { |
| 31 return is_active ? ServiceWorkerVersion::ACTIVE |
| 32 : ServiceWorkerVersion::INSTALLED; |
| 33 } |
| 34 |
| 28 } // namespace | 35 } // namespace |
| 29 | 36 |
| 30 ServiceWorkerStorage::ServiceWorkerStorage( | 37 ServiceWorkerStorage::ServiceWorkerStorage( |
| 31 const base::FilePath& path, | 38 const base::FilePath& path, |
| 32 base::WeakPtr<ServiceWorkerContextCore> context, | 39 base::WeakPtr<ServiceWorkerContextCore> context, |
| 33 quota::QuotaManagerProxy* quota_manager_proxy) | 40 quota::QuotaManagerProxy* quota_manager_proxy) |
| 34 : last_registration_id_(0), | 41 : last_registration_id_(0), |
| 35 last_version_id_(0), | 42 last_version_id_(0), |
| 36 last_resource_id_(0), | 43 last_resource_id_(0), |
| 37 simulated_lazy_initted_(false), | 44 simulated_lazy_initted_(false), |
| (...skipping 24 matching lines...) Expand all Loading... |
| 62 if (found == stored_registrations_.end()) { | 69 if (found == stored_registrations_.end()) { |
| 63 RunSoon(base::Bind( | 70 RunSoon(base::Bind( |
| 64 callback, SERVICE_WORKER_ERROR_NOT_FOUND, | 71 callback, SERVICE_WORKER_ERROR_NOT_FOUND, |
| 65 null_registration)); | 72 null_registration)); |
| 66 return; | 73 return; |
| 67 } | 74 } |
| 68 | 75 |
| 69 // Find one with a matching scope. | 76 // Find one with a matching scope. |
| 70 for (RegistrationsMap::const_iterator it = found->second.begin(); | 77 for (RegistrationsMap::const_iterator it = found->second.begin(); |
| 71 it != found->second.end(); ++it) { | 78 it != found->second.end(); ++it) { |
| 72 if (scope == it->second.scope) { | 79 if (scope == GURL(it->second.scope_url())) { |
| 73 const ServiceWorkerDatabase::RegistrationData* data = &(it->second); | 80 const ServiceWorkerRegistrationData* data = &(it->second); |
| 74 scoped_refptr<ServiceWorkerRegistration> registration = | 81 scoped_refptr<ServiceWorkerRegistration> registration = |
| 75 context_->GetLiveRegistration(data->registration_id); | 82 context_->GetLiveRegistration(data->registration_id()); |
| 76 if (registration) { | 83 if (registration) { |
| 77 RunSoon(base::Bind( | 84 RunSoon(base::Bind( |
| 78 callback, SERVICE_WORKER_OK, | 85 callback, SERVICE_WORKER_OK, |
| 79 registration)); | 86 registration)); |
| 80 return; | 87 return; |
| 81 } | 88 } |
| 82 | 89 |
| 83 registration = CreateRegistration(data); | 90 registration = CreateRegistration(data); |
| 84 RunSoon(base::Bind(callback, SERVICE_WORKER_OK, registration)); | 91 RunSoon(base::Bind(callback, SERVICE_WORKER_OK, registration)); |
| 85 return; | 92 return; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 109 // origins with registrations. | 116 // origins with registrations. |
| 110 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND, null_registration); | 117 callback.Run(SERVICE_WORKER_ERROR_NOT_FOUND, null_registration); |
| 111 return; | 118 return; |
| 112 } | 119 } |
| 113 | 120 |
| 114 // Find one with a pattern match. | 121 // Find one with a pattern match. |
| 115 for (RegistrationsMap::const_iterator it = found->second.begin(); | 122 for (RegistrationsMap::const_iterator it = found->second.begin(); |
| 116 it != found->second.end(); ++it) { | 123 it != found->second.end(); ++it) { |
| 117 // TODO(michaeln): if there are multiple matches the one with | 124 // TODO(michaeln): if there are multiple matches the one with |
| 118 // the longest scope should win. | 125 // the longest scope should win. |
| 119 if (ServiceWorkerUtils::ScopeMatches(it->second.scope, document_url)) { | 126 if (ServiceWorkerUtils::ScopeMatches( |
| 120 const ServiceWorkerDatabase::RegistrationData* data = &(it->second); | 127 GURL(it->second.scope_url()), document_url)) { |
| 128 const ServiceWorkerRegistrationData* data = &(it->second); |
| 121 | 129 |
| 122 // If its in the live map, return syncly to simulate this class having | 130 // If its in the live map, return syncly to simulate this class having |
| 123 // iterated over the values in that map instead of reading the db. | 131 // iterated over the values in that map instead of reading the db. |
| 124 scoped_refptr<ServiceWorkerRegistration> registration = | 132 scoped_refptr<ServiceWorkerRegistration> registration = |
| 125 context_->GetLiveRegistration(data->registration_id); | 133 context_->GetLiveRegistration(data->registration_id()); |
| 126 if (registration) { | 134 if (registration) { |
| 127 callback.Run(SERVICE_WORKER_OK, registration); | 135 callback.Run(SERVICE_WORKER_OK, registration); |
| 128 return; | 136 return; |
| 129 } | 137 } |
| 130 | 138 |
| 131 // If we have to create a new instance, return it asyncly to simulate | 139 // If we have to create a new instance, return it asyncly to simulate |
| 132 // having had to retreive the RegistrationData from the db. | 140 // having had to retreive the RegistrationData from the db. |
| 133 registration = CreateRegistration(data); | 141 registration = CreateRegistration(data); |
| 134 RunSoon(base::Bind(callback, SERVICE_WORKER_OK, registration)); | 142 RunSoon(base::Bind(callback, SERVICE_WORKER_OK, registration)); |
| 135 return; | 143 return; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 | 187 |
| 180 for (RegistrationPtrMap::const_iterator it = registrations_by_id_.begin(); | 188 for (RegistrationPtrMap::const_iterator it = registrations_by_id_.begin(); |
| 181 it != registrations_by_id_.end(); ++it) { | 189 it != registrations_by_id_.end(); ++it) { |
| 182 ServiceWorkerRegistration* registration = | 190 ServiceWorkerRegistration* registration = |
| 183 context_->GetLiveRegistration(it->first); | 191 context_->GetLiveRegistration(it->first); |
| 184 if (registration) { | 192 if (registration) { |
| 185 registrations.push_back(registration->GetInfo()); | 193 registrations.push_back(registration->GetInfo()); |
| 186 continue; | 194 continue; |
| 187 } | 195 } |
| 188 ServiceWorkerRegistrationInfo info; | 196 ServiceWorkerRegistrationInfo info; |
| 189 info.pattern = it->second->scope; | 197 info.pattern = GURL(it->second->scope_url()); |
| 190 info.script_url = it->second->script; | 198 info.script_url = GURL(it->second->script_url()); |
| 191 info.active_version.is_null = false; | 199 info.active_version.is_null = false; |
| 192 if (it->second->is_active) | 200 if (it->second->is_active()) |
| 193 info.active_version.status = ServiceWorkerVersion::ACTIVE; | 201 info.active_version.status = ServiceWorkerVersion::ACTIVE; |
| 194 else | 202 else |
| 195 info.active_version.status = ServiceWorkerVersion::INSTALLED; | 203 info.active_version.status = ServiceWorkerVersion::INSTALLED; |
| 196 registrations.push_back(info); | 204 registrations.push_back(info); |
| 197 } | 205 } |
| 198 | 206 |
| 199 RunSoon(base::Bind(callback, registrations)); | 207 RunSoon(base::Bind(callback, registrations)); |
| 200 } | 208 } |
| 201 | 209 |
| 202 void ServiceWorkerStorage::StoreRegistration( | 210 void ServiceWorkerStorage::StoreRegistration( |
| 203 ServiceWorkerRegistration* registration, | 211 ServiceWorkerRegistration* registration, |
| 204 ServiceWorkerVersion* version, | 212 ServiceWorkerVersion* version, |
| 205 const StatusCallback& callback) { | 213 const StatusCallback& callback) { |
| 206 DCHECK(registration); | 214 DCHECK(registration); |
| 207 DCHECK(version); | 215 DCHECK(version); |
| 208 DCHECK(simulated_lazy_initted_); | 216 DCHECK(simulated_lazy_initted_); |
| 209 if (!context_) { | 217 if (!context_) { |
| 210 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); | 218 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); |
| 211 return; | 219 return; |
| 212 } | 220 } |
| 213 | 221 |
| 214 // Keep a database struct in the storage map. | 222 // Keep a database struct in the storage map. |
| 215 RegistrationsMap& storage_map = | 223 RegistrationsMap& storage_map = |
| 216 stored_registrations_[registration->script_url().GetOrigin()]; | 224 stored_registrations_[registration->script_url().GetOrigin()]; |
| 217 ServiceWorkerDatabase::RegistrationData& data = | 225 ServiceWorkerRegistrationData& data = storage_map[registration->id()]; |
| 218 storage_map[registration->id()]; | 226 data.set_registration_id(registration->id()); |
| 219 data.registration_id = registration->id(); | 227 data.set_scope_url(registration->pattern().spec()); |
| 220 data.scope = registration->pattern(); | 228 data.set_script_url(registration->script_url().spec()); |
| 221 data.script = registration->script_url(); | 229 data.set_has_fetch_handler(true); |
| 222 data.has_fetch_handler = true; | 230 data.set_version_id(version->version_id()); |
| 223 data.version_id = version->version_id(); | 231 data.set_last_update_check_time(base::Time::Now().ToInternalValue()); |
| 224 data.last_update_check = base::Time::Now(); | 232 data.set_is_active(false); // initially stored in the waiting state |
| 225 data.is_active = false; // initially stored in the waiting state | |
| 226 | 233 |
| 227 // Keep a seperate map of ptrs keyed by id only. | 234 // Keep a seperate map of ptrs keyed by id only. |
| 228 registrations_by_id_[registration->id()] = &storage_map[registration->id()]; | 235 registrations_by_id_[registration->id()] = &storage_map[registration->id()]; |
| 229 | 236 |
| 230 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 237 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
| 231 } | 238 } |
| 232 | 239 |
| 233 void ServiceWorkerStorage::UpdateToActiveState( | 240 void ServiceWorkerStorage::UpdateToActiveState( |
| 234 ServiceWorkerRegistration* registration, | 241 ServiceWorkerRegistration* registration, |
| 235 const StatusCallback& callback) { | 242 const StatusCallback& callback) { |
| 236 DCHECK(simulated_lazy_initted_); | 243 DCHECK(simulated_lazy_initted_); |
| 237 if (!context_) { | 244 if (!context_) { |
| 238 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); | 245 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_FAILED)); |
| 239 return; | 246 return; |
| 240 } | 247 } |
| 241 | 248 |
| 242 RegistrationPtrMap::const_iterator | 249 RegistrationPtrMap::const_iterator |
| 243 found = registrations_by_id_.find(registration->id()); | 250 found = registrations_by_id_.find(registration->id()); |
| 244 if (found == registrations_by_id_.end()) { | 251 if (found == registrations_by_id_.end()) { |
| 245 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); | 252 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); |
| 246 return; | 253 return; |
| 247 } | 254 } |
| 248 DCHECK(!found->second->is_active); | 255 DCHECK(!found->second->is_active()); |
| 249 found->second->is_active = true; | 256 found->second->set_is_active(true); |
| 250 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 257 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
| 251 } | 258 } |
| 252 | 259 |
| 253 void ServiceWorkerStorage::DeleteRegistration( | 260 void ServiceWorkerStorage::DeleteRegistration( |
| 254 int64 registration_id, | 261 int64 registration_id, |
| 255 const StatusCallback& callback) { | 262 const StatusCallback& callback) { |
| 256 DCHECK(simulated_lazy_initted_); | 263 DCHECK(simulated_lazy_initted_); |
| 257 RegistrationPtrMap::iterator | 264 RegistrationPtrMap::iterator |
| 258 found = registrations_by_id_.find(registration_id); | 265 found = registrations_by_id_.find(registration_id); |
| 259 if (found == registrations_by_id_.end()) { | 266 if (found == registrations_by_id_.end()) { |
| 260 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); | 267 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_NOT_FOUND)); |
| 261 return; | 268 return; |
| 262 } | 269 } |
| 263 | 270 |
| 264 GURL origin = found->second->script.GetOrigin(); | 271 GURL origin = GURL(found->second->script_url()).GetOrigin(); |
| 265 stored_registrations_[origin].erase(registration_id); | 272 stored_registrations_[origin].erase(registration_id); |
| 266 if (stored_registrations_[origin].empty()) | 273 if (stored_registrations_[origin].empty()) |
| 267 stored_registrations_.erase(origin); | 274 stored_registrations_.erase(origin); |
| 268 | 275 |
| 269 registrations_by_id_.erase(found); | 276 registrations_by_id_.erase(found); |
| 270 | 277 |
| 271 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); | 278 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); |
| 272 // TODO(michaeln): Either its instance should also be | 279 // TODO(michaeln): Either its instance should also be |
| 273 // removed from liveregistrations map or the live object | 280 // removed from liveregistrations map or the live object |
| 274 // should marked as deleted in some way and not 'findable' | 281 // should marked as deleted in some way and not 'findable' |
| (...skipping 10 matching lines...) Expand all Loading... |
| 285 return ++last_version_id_; | 292 return ++last_version_id_; |
| 286 } | 293 } |
| 287 | 294 |
| 288 int64 ServiceWorkerStorage::NewResourceId() { | 295 int64 ServiceWorkerStorage::NewResourceId() { |
| 289 DCHECK(simulated_lazy_initted_); | 296 DCHECK(simulated_lazy_initted_); |
| 290 return ++last_resource_id_; | 297 return ++last_resource_id_; |
| 291 } | 298 } |
| 292 | 299 |
| 293 scoped_refptr<ServiceWorkerRegistration> | 300 scoped_refptr<ServiceWorkerRegistration> |
| 294 ServiceWorkerStorage::CreateRegistration( | 301 ServiceWorkerStorage::CreateRegistration( |
| 295 const ServiceWorkerDatabase::RegistrationData* data) { | 302 const ServiceWorkerRegistrationData* data) { |
| 296 scoped_refptr<ServiceWorkerRegistration> registration( | 303 scoped_refptr<ServiceWorkerRegistration> registration( |
| 297 new ServiceWorkerRegistration( | 304 new ServiceWorkerRegistration( |
| 298 data->scope, data->script, data->registration_id, context_)); | 305 GURL(data->scope_url()), GURL(data->script_url()), |
| 306 data->registration_id(), context_)); |
| 299 | 307 |
| 300 scoped_refptr<ServiceWorkerVersion> version = | 308 scoped_refptr<ServiceWorkerVersion> version = |
| 301 context_->GetLiveVersion(data->version_id); | 309 context_->GetLiveVersion(data->version_id()); |
| 302 if (!version) { | 310 if (!version) { |
| 303 version = new ServiceWorkerVersion( | 311 version = new ServiceWorkerVersion( |
| 304 registration, data->version_id, context_); | 312 registration, data->version_id(), context_); |
| 305 version->SetStatus(data->GetVersionStatus()); | 313 version->SetStatus(GetVersionStatus(data->is_active())); |
| 306 } | 314 } |
| 307 | 315 |
| 308 if (version->status() == ServiceWorkerVersion::ACTIVE) | 316 if (version->status() == ServiceWorkerVersion::ACTIVE) |
| 309 registration->set_active_version(version); | 317 registration->set_active_version(version); |
| 310 else if (version->status() == ServiceWorkerVersion::INSTALLED) | 318 else if (version->status() == ServiceWorkerVersion::INSTALLED) |
| 311 registration->set_pending_version(version); | 319 registration->set_pending_version(version); |
| 312 else | 320 else |
| 313 NOTREACHED(); | 321 NOTREACHED(); |
| 314 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after | 322 // TODO(michaeln): Hmmm, what if DeleteReg was invoked after |
| 315 // the Find result we're returning here? NOTREACHED condition? | 323 // the Find result we're returning here? NOTREACHED condition? |
| 316 | 324 |
| 317 return registration; | 325 return registration; |
| 318 } | 326 } |
| 319 | 327 |
| 320 } // namespace content | 328 } // namespace content |
| OLD | NEW |